Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala case类中的产品继承_Scala_Inheritance_Case Class - Fatal编程技术网

Scala case类中的产品继承

Scala case类中的产品继承,scala,inheritance,case-class,Scala,Inheritance,Case Class,我有一些扩展公共超类的case类,我想使用productElement方法访问超类中的字段(我曾尝试将基类声明为case类,但我得到了一个关于case类继承危险的可怕警告,但仍然不起作用) 我可以想象这样的解决方案: abstract class A(a: Int) extends Product { def productArity = 1 def productElement(n: Int) = if (n == 0) a else throw new IndexOutOfBound

我有一些扩展公共超类的case类,我想使用
productElement
方法访问超类中的字段(我曾尝试将基类声明为case类,但我得到了一个关于case类继承危险的可怕警告,但仍然不起作用)

我可以想象这样的解决方案:

abstract class A(a: Int) extends Product {
  def productArity = 1
  def productElement(n: Int) = if (n == 0) a else throw new IndexOutOfBoundsException
}

case class B(b: Int) extends A(1) {
  def productArity = super.productArity + 1  
  def productElement(n: Int) = if (n < super.productArity) super.productElement(n) else ....
}
抽象类A(A:Int)扩展了产品{
def生产率=1
def productElement(n:Int)=如果(n==0)else抛出新的IndexOutOfBoundsException
}
案例类别B(B:Int)扩展了A(1){
def productArity=super.productArity+1
def productElement(n:Int)=如果(n
但它变得如此丑陋,我甚至无法完成


有谁知道更好的解决方案吗?

我能找到的最接近的方法是不在

scala> abstract class A(val a: Int) extends Product
defined class A

scala> case class B(override val a: Int, b: String) extends A(a)
defined class B

scala> val anA: A = B(42, "banana")
anA: A = B(42,banana)

scala> anA.a
res37: Int = 42

scala> anA.productArity
res38: Int = 2

scala> anA.productElement(1)
res39: Any = banana

scala> anA.productElement(0)
res40: Any = 42

在Scala主干中,已经为您完成了很多工作:case类现在扩展了适当的ProductN特性。但是,产品中只包含case类直接(即非继承)成员,因此如果需要包含来自超级类型的成员,它们必须在超级类型中是抽象的,并在case类中提供具体的实现

这是一个REPL会话(Scala trunk,2.10.0.r25951-b20111107020214)


你能把
A
变成
抽象案例类吗?
?是的,我已经做到了,我明白了:案例间继承有潜在的危险缺陷,不太可能被修复。强烈建议您改用提取器在非叶节点上进行模式匹配。而且它不起作用。谢谢你的主意!这让我想到了另一个解决方案:
抽象类A(val A:Int)扩展产品
案例类B(B:String,override val A:Int=42)扩展A(A)
唯一的缺点是,对于所有子类,“A”不会处于相同的位置。谢谢,您的解决方案看起来比以前的(
抽象类
)更好,但我仍然想不出一个办法,把继承的成员放在第一位。我想避免一些笨拙的代码,比如
x.productElement(x.productArity-1)
,因为某种原因,它在2.10中被删除了。你知道为什么吗?@Blaisorblade我忘记了魔鬼隐藏的细节,但你可以跟踪进度(或缺乏进度)。@MilesSabin:谢谢你的链接。
scala> trait A { val a: Int }
defined trait A

scala> case class B(b: Int, a : Int = 1) extends A                                                                                                                                                     
defined class B                                                                                                                                                                                        

scala> val b = B(23)
b: B = B(23,1)                                                                                                                                                                                         

scala> b.productArity
res0: Int = 2                                                                                                                                                                                          

scala> b.productElement(0)
res1: Any = 23                                                                                                                                                                                         

scala> b.productElement(1)
res2: Any = 1                                                                                                                                                                                          

scala> b._1      // use Product method ... note result type
res6: Int = 23                                                                                                                                                                                         

scala> b._2      // use Product method ... note result type                                                                                                                                                                                            
res7: Int = 1