Scala 为什么案例类只扩展Product而不扩展Product1、Product2、…、ProductN?

Scala 为什么案例类只扩展Product而不扩展Product1、Product2、…、ProductN?,scala,scala-2.9,Scala,Scala 2.9,在我了解到案例类扩展了Product之后,我想知道为什么它们不扩展ProductN。例如,给定如下代码: case class Foo(a: Int) 我希望Foo(1).asInstanceOf[Product1[Int]]能起作用,但它不能起作用(通过Scala 2.9.1进行检查,并通过其他来源和Product文档进行确认) 我对此很感兴趣,因为我想声明如下类: abstract class UnaryOp[T1 <: Exp[_], R](t1: T1) extends Exp[

在我了解到案例类扩展了Product之后,我想知道为什么它们不扩展ProductN。例如,给定如下代码:

case class Foo(a: Int)
我希望
Foo(1).asInstanceOf[Product1[Int]]
能起作用,但它不能起作用(通过Scala 2.9.1进行检查,并通过其他来源和
Product
文档进行确认)

我对此很感兴趣,因为我想声明如下类:

abstract class UnaryOp[T1 <: Exp[_], R](t1: T1) extends Exp[R] {
  this: Product1[T1] =>
}
抽象类UnaryOp[T1
}

这样,一元操作的节点必须是implementproduct1。如果只是一个带有一个参数的case类就足够了,那就太好了。

if
Product1[Int]
将自动扩展
val\u 1:Int
也必须提供。虽然我可以想象,
a
可以自动分配给
\u 1
等,但事实并非如此。可能只是为了不让事情变得更复杂。

考虑一下:

case class X(n: Int)
case class Y(x: String, y: Int) extends X(y)
如果案例类扩展了
ProductN
,那么这将扩展
Product1
Product2
,但是类型参数会发生变化,因此
\u 1
有两种不同的重载。这只是一个问题——我打赌还有其他问题


现在,继承case类的case类已经被弃用,Martin Odersky正在考虑让他们继承ProductN。AFAIK,还没有完成,但障碍已经消除。

在Martin说我们可以完成后不久,我就把它带回来了。它还没有正常工作,但在某种程度上,它已经落后于-Xexperimenta了l在主干构建中

scala> case class Foo[T, U](x1: T, x2: U)
defined class Foo

scala> Foo(List("a"), "b")
res0: Foo[List[java.lang.String],java.lang.String] = Foo(List(a),b)

scala> res0.isInstanceOf[Product2[_,_]]
res1: Boolean = true

是的,希望这将使其成为未来的Scala版本,因为它允许编写类型安全的、通用的案例类分解函数。是否可以在Scala中继承案例类?鉴于自您提供此答案以来Scala发生了多大变化,特别是您上面描述的案例类继承已被弃用我的Scala版本s以前(早在2.12…当前版本之前),这个问题现在又开始了。它是否有可能最终被添加到Scala 2.x行?是否有可能Scala 3(Dotty)已经解决了这个问题,如果是这样的话,则被后移植到2.x行?添加
val\u 1:Int
会在每个实例中浪费内存,但
Product1[T]
有一个抽象定义
def\u 1:T
,为它添加一个实现(
def\u 1:T=a
)不会改变实例大小。请参见Daniel C.Sobral的答案!这里会发生什么?案例类C(\u 2:String,\u 1:Int)谢谢,那太好了-很高兴在下一个Scala版本中有这样的版本!我不确定该接受哪个答案,但最终我认为我还是必须接受Daniel C.Sobral的答案,因为他提供了解释。我在2.10.0-M5中尝试了这一点,结果令人困惑。_1和_2出现在Foo上,但它不是Product2的子类型,这些membeScaladoc没有记录R:
scala>Foo(列表(“a”),“b”)res10:Foo[List[String],String]=Foo(列表(a),b)scala>res10.isInstanceOf[Product2[u,]]res11:Boolean=false scala>res10.\u 1 res12:List[String]=List(a)scala>Some(1)._1 res13:Int=1
如果从另一个case类继承的case类被弃用,那么发生了什么?它是否有可能出现在当前的2.x版本和/或Scala 3(Dotty)中?我对这里的否决票感到困惑。否决票可以解释一下吗?