对于 `case class Cc(a: Int, b: Int) extends MyTraitA`,带有 `Product` 和 `Serializable` 特征的 `MyTraitA` 出现在哪里?
For `case class Cc(a: Int, b: Int) extends MyTraitA`, where does `MyTraitA` appear with `Product` and `Serializable` traits?
由于 Scala 中的继承线性化,我想了解我为案例 class 指定的特征是如何相对于 Scala 编译器自动生成和添加的两个特征进行排序的;即 Product with Serializable
(令人失望的是,从 2.12 开始它不是 ProductN[...]
)。
我已经彻底搜索过了,但没有找到直接解决的问题。鉴于以下内容:
case class Cc(a: Int, b: Int) extends MyTraitA with MyTraitB
在 Scala 编译器自动代码生成之后,关于结果继承顺序的以下哪项假设是正确的?
case class Cc(a: Int, b: Int) extends MyTraitA with MyTraitB with Product with Serializable
case class Cc(a: Int, b: Int) extends Product with Serializable with MyTraitA with MyTraitB
然后,我还有一个问题。如果我将 Product2[...]
显式扩展到案例 class,会发生什么不良或意外的结果?以下是上面插入的 Product2[...]
重复的两段代码:
case class Cc(a: Int, b: Int) extends MyTraitA with MyTraitB with Product2[Int, Int] with Product with Serializable
case class Cc(a: Int, b: Int) extends Product with Serializable with MyTraitA with MyTraitB with Product2[Int, Int]
IOW,由于 Product
和 Product2
一起出现,是否存在任何不良交互?
感谢深入阅读 Bogdan Vakulenko 在评论中提供的 link,第一个问题的明确答案是第 2 项:
case class Cc(a: Int, b: Int) extends Product with Serializable with MyTraitA with MyTraitB
再次感谢 Bogdan Vakulenko,第二个问题的答案是添加 Product2[Int, Int]
特征时不会出现任何不良情况,因为它扩展了 Product
特征。
有个加分答案很有意思。如果希望将编译器生成的接口推到特征继承顺序的后面,则需要显式定义编译器生成的接口。有几种方法可以做到这一点。
第一个也是最简单的方法是更改如下所示的原始代码(不引用 Product
和 Serializable
并让编译器自动生成它们):
case class Cc(a: Int, b: Int) extends MyTraitA with MyTraitB
显示为这样(在特征列表的尾部明确定义 Product
和 Serializable
):
case class Cc(a: Int, b: Int) extends MyTraitA with MyTraitB with Product with Serializable
第二个选项是将 Product with Serializable
添加到 MyTraitA
and/or MyTraitB
的 both/either 中:
trait MyTraitA extends Product with Serializable
trait MyTraitB extends Product with Serializable
case class Cc(a: Int, b: Int) extends MyTraitA with MyTraitB
此技术还可以产生理想的特征排序。
case class Cc(a: Int, b: Int) extends MyTraitA with MyTraitB with Product with Serializable
最后,集成 Product2[Int, Int]
就像显式定义一切一样简单,知道任何重叠都将通过 Scala 编译器默认提供的优秀多重继承解析策略自动解决:
case class Cc(a: Int, b: Int) extends MyTraitA with MyTraitB with Product2[Int, Int] with Product with Serializable {
override def _1: Int = a
override def _2: Int = b
}
由于 Scala 中的继承线性化,我想了解我为案例 class 指定的特征是如何相对于 Scala 编译器自动生成和添加的两个特征进行排序的;即 Product with Serializable
(令人失望的是,从 2.12 开始它不是 ProductN[...]
)。
我已经彻底搜索过了,但没有找到直接解决的问题。鉴于以下内容:
case class Cc(a: Int, b: Int) extends MyTraitA with MyTraitB
在 Scala 编译器自动代码生成之后,关于结果继承顺序的以下哪项假设是正确的?
case class Cc(a: Int, b: Int) extends MyTraitA with MyTraitB with Product with Serializable
case class Cc(a: Int, b: Int) extends Product with Serializable with MyTraitA with MyTraitB
然后,我还有一个问题。如果我将 Product2[...]
显式扩展到案例 class,会发生什么不良或意外的结果?以下是上面插入的 Product2[...]
重复的两段代码:
case class Cc(a: Int, b: Int) extends MyTraitA with MyTraitB with Product2[Int, Int] with Product with Serializable
case class Cc(a: Int, b: Int) extends Product with Serializable with MyTraitA with MyTraitB with Product2[Int, Int]
IOW,由于 Product
和 Product2
一起出现,是否存在任何不良交互?
感谢深入阅读 Bogdan Vakulenko 在评论中提供的 link,第一个问题的明确答案是第 2 项:
case class Cc(a: Int, b: Int) extends Product with Serializable with MyTraitA with MyTraitB
再次感谢 Bogdan Vakulenko,第二个问题的答案是添加 Product2[Int, Int]
特征时不会出现任何不良情况,因为它扩展了 Product
特征。
有个加分答案很有意思。如果希望将编译器生成的接口推到特征继承顺序的后面,则需要显式定义编译器生成的接口。有几种方法可以做到这一点。
第一个也是最简单的方法是更改如下所示的原始代码(不引用 Product
和 Serializable
并让编译器自动生成它们):
case class Cc(a: Int, b: Int) extends MyTraitA with MyTraitB
显示为这样(在特征列表的尾部明确定义 Product
和 Serializable
):
case class Cc(a: Int, b: Int) extends MyTraitA with MyTraitB with Product with Serializable
第二个选项是将 Product with Serializable
添加到 MyTraitA
and/or MyTraitB
的 both/either 中:
trait MyTraitA extends Product with Serializable
trait MyTraitB extends Product with Serializable
case class Cc(a: Int, b: Int) extends MyTraitA with MyTraitB
此技术还可以产生理想的特征排序。
case class Cc(a: Int, b: Int) extends MyTraitA with MyTraitB with Product with Serializable
最后,集成 Product2[Int, Int]
就像显式定义一切一样简单,知道任何重叠都将通过 Scala 编译器默认提供的优秀多重继承解析策略自动解决:
case class Cc(a: Int, b: Int) extends MyTraitA with MyTraitB with Product2[Int, Int] with Product with Serializable {
override def _1: Int = a
override def _2: Int = b
}