Scala case类中的产品继承
我有一些扩展公共超类的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
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