本文介绍了具有类型参数的案例类的元组方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

当案例类带有类型参数时,我看不到如何调用 tupled 方法.似乎可以通过 applyunapply 找到.

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(定义 tupledN >= 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]

这篇关于具有类型参数的案例类的元组方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-09 02:12