具有类型参数的案例类的Tupled方法

时间:2014-08-17 00:19:05

标签: scala case-class

当有一个带有类型参数的case类时,我看不出如何调用tupled方法。似乎可以找到applyunapply

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] _
              ^

对于发生了什么有任何想法?

1 个答案:

答案 0 :(得分:15)

TL;博士

案例类的伴随对象在具有类型参数时无法扩展FunctionN(定义{{​​1}},tupled&gt; = 2)。使用

N

讨论

当你有一个像

这样的香草类时
(Foo[Int] _).tupled

它的构造函数实际上是case class Bar(x: Int, y: Int) ,因此当编译器生成伴随对象Function2[Int, Int, Bar]时,它可以方便地扩展Bar

生成的代码将是

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)

由于// this can't compile, what's T? object Foo extends Function2[T, T, Bar] with Serializable { ... } 未知,编译器无法使T成为Foo的子类,并且它不能比扩展Function2做得更好:< / p>

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