问题描述
当案例类带有类型参数时,我看不到如何调用 tupled
方法.似乎可以通过 apply
和 unapply
找到.
When having a case class with a type parameter, I don't see how I can call the tupled
method. It seems to be find with apply
and unapply
.
scala> case class Foo[T](x:T, y:T)
defined class Foo
scala> Foo.apply[Int] _
res1: (Int, Int) => Foo[Int] = <function2>
scala> Foo.unapply[Int] _
res2: Foo[Int] => Option[(Int, Int)] = <function1>
scala> Foo.tupled[Int] _
<console>:10: error: value tupled is not a member of object Foo
Foo.tupled[Int] _
^
知道发生了什么吗?
推荐答案
tl;dr
case 类的伴随对象在具有类型参数时不能扩展 FunctionN
(定义 tupled
,N
>= 2).使用
tl;dr
Companion objects of case classes cannot extend FunctionN
(which defines tupled
, with N
>= 2) when they have type parameters. Use
(Foo[Int] _).tupled
讨论
当你有一个普通的类,比如
discussion
When you have a vanilla class such as
case class Bar(x: Int, y: Int)
它的构造函数实际上是一个Function2[Int, Int, Bar]
,因此当编译器生成伴随对象Bar
时,它可以方便地扩展Function2代码>.
its constructor is effectively a Function2[Int, Int, Bar]
, hence when the compiler generates the companion object Bar
it can conveniently make it extend Function2
.
生成的代码将是
class Bar extends AnyRef with Product with Serializable { ... }
object Bar extends Function2[Int, Int, Bar] with Serializable { ... }
现在考虑
case class Foo[T](x: T, y: T)
如果您尝试应用相同的技巧,您很快就会发现自己陷入困境:
If you try to apply the same trick, you'll find yourself in trouble very soon:
// this can't compile, what's T?
object Foo extends Function2[T, T, Bar] with Serializable { ... }
由于 T
是未知的,编译器不能使 Foo
成为 Function2
的子类,它不能比 make 做得更好它扩展了 AnyRef
:
Since T
is unknown, the compiler can't make Foo
a subclass of Function2
and it can't do much better than make it extend AnyRef
:
class Foo[T] extends AnyRef with Product with Serializable { ... }
object Foo extends AnyRef with Serializable { ... }
以下是上述讨论内容的快速证明(使用 scala -Xprint:typer
):
scala> case class Bar(x: Int, y: Int)
...
<synthetic> object Bar extends scala.runtime.AbstractFunction2[Int,Int,Bar] with Serializable {
...
scala> case class Foo[T](x: T, y: T)
...
<synthetic> object Foo extends AnyRef with Serializable {
...
总结一下,当你有类型参数时,你必须先获得一个Function2
val f: Function2[Int, Int, Foo] = Foo[Int] _
然后你可以调用tupled
f.tupled // ((Int, Int)) => Foo[Int]
这篇关于具有类型参数的案例类的元组方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!