2012-06-23 49 views
4

这是一个令我头痛的特质线性化益智游戏。我基本上输入了Node,它定义了equalshashCode与其他Node s进行比较。而且我有一个Selector类型,它可能包含Node以及额外的数据,因此有其自己的equalshashCode可与其他Selector进行比较。搞砸特质线性化?

现在我有一个Standalone型相结合的NodeSelector,但我得到不一致的关于线性化,以equalshashCode(?):

trait Selector { override def hashCode = 1 } 
trait Event extends Selector 

trait Node { override def hashCode = 2 } 
trait Standalone extends Node with Event 

现在一切都很好(更具体的hashCode 1被称为)当我从任一EventStandalone延伸:

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图(混入由左到右排列):

enter image description here

所以,如果我正确理解linearisation rules,我应该总是以Selector执行hashCode。对于这种行为的唯一解释是,涉及某种贪婪/深度优先的事物......?

此外,如果有一种技术,我可以使用,以确保无论何时Standalone混入,确保了Selector否决Node(比SelectorStandalone复制equalshashCode等),这将是非常赞赏。

这是与斯卡拉2.9.2。

回答

4

最好去规范这种事情。 该算法描述如下5.1.2 Class Linearization

解释它,类C的线性化是C,然后从最右边的项目开始线性化它扩展的事物。然后,最后一步是去除线性化中的重复项,只保留最右边的项。

在你的榜样

所以对于Compound1(忽略内置插件一样AnyRef):
L(Compound1) = Compound1 + L(Event) + L(Standalone)
L(Event) = Event + L(Selector)
L(Selector) = Selector
L(Standalone) = Standalone + L(Event) + L(Node)
L(Node) = Node
将其组合在一起:
L(Compound1) = Compound1 Event Selector Standalone Event Selector Node
删除重复项:
Compound1 Standalone Event Selector Node

对于Compound2它最终被:
Compound2 Standalone Node Event Selector


至于其他的问题,我认为最简单的方法是将覆盖Standalone的方法,并调用所需的方法在超类。

trait Standalone extends Node with Event { override def hashCode = super[Event].hashCode } 

假设这不是你的意思是“复制”。

+0

_keeping只有最右边的一个_...好的,这样看来是问题了。我想没有办法在'Standalone'中重新实现这些方法...... –

+0

'Standalone'在两个对象的线性化中位于'Node'和'Selector'之前,因此您可以在其中覆盖它。然而,这一切对我来说似乎都很脆弱,你可能会更好地重新设计它。 – Kaito