我试图在节点与其父节点之间的图形中强制实施类型关系。 我有以下不能编译child.parents :: = this。 任何评论都会受到欢迎
trait TGraphNode {
type NodeType <: TGraphNode
var id = -1
var parents = List[NodeType]()
var children = List[TGraphNode]()
def addChild(child: NodeType) {
children ::= child
child.parents ::= this
}
override def toString = "node-"+id+"->"+children
}
抱歉 - 下次会添加编译错误。我试图实现以下目标:想象我有2个类型为F和C的节点 - 我想通过构造强制执行C只能将F作为父级,但是,反过来我不在乎。 F可以有C,D ..作为孩子。所以我想捕获可以在实现特征的类中覆盖ParentType。
class F extends TGraphNode ...
class B extends TGraphNode {
type ParentType = F
}
由于
答案 0 :(得分:2)
错误消息是
error: Type mismatch
found : TGraphNode.this.type (with underlying type TGraphNode)
required: child.NodeType
child.parents ::= this
(请不要在你的问题中省略)
您的代码声明节点可以选择其父项所需的类型,类型为变量NodeType
。这种类型必须符合TGraphNode,但它可能比这更受限制。
鉴于此,child
中添加的addChild
可能需要比this
更为受限的类型作为其父级。编译器拒绝这一点是正确的。
这是错误消息所说的内容:
您将this
放在子项的父级列表中。 this
的类型为TGraphNode
。
但是parents
列表是孩子NodeType
的列表(child.NodeType
)
没有保证比类型匹配。
如果你不解释你想要实现的目标,我不能进一步评论。
编辑后:
您必须声明您将在addChild中仅接受将其接受为父级的子级。这可能有点棘手,这可能是一种方式:
def addChild[N](child: TGraphNode{type NodeType = N})
(implicit thisAsParentOfChild : this.type <:< N) {
children ::= child
child.parents ::= thisAsParentOfChild(this)
}
完成后,你现在可以做
class F extends TGraphNode {type NodeType = TGraphNode }
class C extends TGraphNode {type NodeType = F }
class X extends TGraphNode {type NodeType = TGraphNode }
val f = new F
val c = new C
val x = new X
f.addChild(c) // ok
x.addChild(f) // ok
x.addChild(c) // error: Cannot prove that x.type <:< F
如果您不知道类型为&lt;:&lt;的隐式参数是什么的确看看What do <:<, <%<, and =:= mean in Scala 2.8, and where are they documented?
在第二次思考和阅读bluenote建议时,在你的语境中写addParent
比addChild
更简单(我相信这是扭转孩子和父母的正确方法):
def addParent(parent: NodeType) {
parents ::= parent
parent.children ::= this
}
答案 1 :(得分:1)
我的猜测是,您只是混淆了NodeType
和TGraphNode
类型。如果我理解正确,孩子可能属于TGraphNode
的子类型。至少这是addChild
函数签名所指示的,并且可能是更可能的用例。因此,孩子必须是NodeType
类型,但父母可以有更一般的TGraphNode
类型,即:
trait TGraphNode {
type NodeType <: TGraphNode
var id = -1
var children = List[NodeType]()
var parents = List[TGraphNode]()
def addChild(child: NodeType) {
children ::= child
child.parents ::= this
}
override def toString = "node-"+id+"->"+children
}
修改强>
好的,你真的想要它反过来。由于上面提到的版本编译,你可以反转孩子和父母的定义,以获得你想要的。