案例类中的产品继承

发布于 2024-12-12 13:21:06 字数 538 浏览 1 评论 0原文

我有一些扩展公共超类的案例类,我想使用 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 ....
}

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

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

I have some case classes that extend a common superclass and I'd like to access fields from the superclass using productElement method (I've tryed to declare base class as a case class but I get a frightening warning about the dangers of inheritance of case classes and yet doesn't work).

I can imagine some solution like this:

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

but it was getting so ugly that I can't even finish.

Does anybody know a better solution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

瑶笙 2024-12-19 13:21:06

在 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

In Scala trunk a lot of this is done for you already: case classes now extend the appropriate ProductN trait. Only case class direct (ie. not inherited) members are included in the product however, so if you need to include members from a super type, they would have to be abstract in the super type and given a concrete implementation in the case class.

Here's a REPL session (Scala trunk, 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
青瓷清茶倾城歌 2024-12-19 13:21:06

我能得到的最接近的是不在 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

The closest I can get is to not implement anything in 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文