【发布时间】:2012-06-23 18:46:54
【问题描述】:
这是一个让我头疼的特征线性化谜题。我基本上输入了Node,它定义了equals 和hashCode,以便与其他Nodes 进行比较。我有一个Selector 类型,它可以包装一个Node 以及额外的数据,因此有自己的equals 和hashCode 可以与其他Selectors 进行比较。
现在我有一个Standalone 类型,它结合了Node 和Selector,但我得到不一致(?)关于equals 和hashCode 的线性化:
trait Selector { override def hashCode = 1 }
trait Event extends Selector
trait Node { override def hashCode = 2 }
trait Standalone extends Node with Event
当我从 Event 或 Standalone 扩展时,现在一切都很好(调用了更具体的 hashCode 1):
object Single1 extends Event
Single1.hashCode // 1 -- ok
object Single2 extends Standalone
Single2.hashCode // 1 -- ok
如果我按这个顺序从两者扩展也很好:
object Compound1 extends Standalone with Event
Compound1.hashCode // 1 -- Ok
但是当我这样做时它搞砸了:
object Compound2 extends Event with Standalone
Compound2.hashCode // 2 -- no!!!!!!!!
我做了一个小点图(mixin 从左到右排序):
所以,如果我正确理解了linearisation rules,我应该总是以Selector 实现的hashCode 结尾。这种行为的唯一解释是涉及某种贪婪/深度优先的事情......?
另外,如果我可以使用一种技术来确保无论何时混入Standalone,都可以确保Selector 优先于Node(除了从@987654350 复制equals 和hashCode @ to Standalone),非常感谢。
这是 Scala 2.9.2。
【问题讨论】:
标签: scala multiple-inheritance traits linearization