2

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

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

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 ....
}

但它变得如此丑陋,我什至无法完成。

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

4

2 回答 2

4

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

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

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
于 2011-11-07T10:07:12.050 回答
1

我能得到的最接近的是不在 A 中实现任何东西

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
于 2011-10-31T18:34:40.960 回答