斯卡拉 – 搞砸了特质线性化?
这是一个让我头疼的特质线性益智游戏.我基本上键入了Node,它定义了equals和hashCode,以便与其他节点进行比较.我有一个Selector类型,它可以包含Node以及额外的数据,因此有自己的equals和hashCode可以与其他选择器进行比较.
现在我有一个Standalone类型,它结合了Node和Selector,但是我得到了与equals和hashCode不一致的(?)linearisation: 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!!!!!!!! 我做了一点.dot图(mixins从左到右排序): 所以,如果我正确理解linearisation rules,我应该总是使用Selector实现的hashCode.对这种行为的唯一解释是,存在某种贪婪/深度优先的事情……? 此外,如果有一种技术我可以用来确保每当Standalone混入时,确保Selector取代Node(除了将Seals和hashCode从Selector复制到Standalone),这将是非常值得赞赏的. 这与Scala 2.9.2有关. 解决方法
这种事情最好去Spec.
该算法在5.1.2类线性化中描述 换句话说,C类的线性化是C,然后是从最右边的项开始扩展的东西的线性化.然后是最后一步,删除线性化中的重复项,只保留最右边的那些. 所以在你的Compound1示例中(忽略像AnyRef这样的内置函数): 对于Compound2,它最终是: 至于另一个问题,我认为最简单的方法是覆盖Standalone中的方法并在超类中调用所需的方法. trait Standalone extends Node with Event { override def hashCode = super[Event].hashCode } 假设这不是你所说的“复制”. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |