我正在尝试创建一个实现具有双向链接的树的特征,这样当节点添加父节点时,该节点就会添加到父节点的子节点中。我得到的错误是:
类型不匹配;发现:PolyTree.this.type(底层类型为PolyTree [T])需要:T
知道为什么这段代码会出现错误以及为了使这段代码工作所需的内容:
trait PolyTree[T <: PolyTree[T]] {
private val _parents: ListBuffer[T] = ListBuffer()
private val _children: ListBuffer[T] = ListBuffer()
def addParent(parent: T): PolyTree[T] = {
if (parent == this)
throw new IllegalArgumentException();
_parents += parent
parent._children += this // Error
this
}
}
答案 0 :(得分:4)
发生错误是因为'parent._children'的类型是'T',而'this'的类型是'PolyTree [T]',它们是Scala中的不同类型。
您可以通过在特征顶部插入以下自我类型注释来修复错误:
self: T =>
这是必要的,因为没有它,以下将是有效的代码:
class TreeOne extends PolyTree[TreeOne]
class TreeTwo extends PolyTree[TreeOne]
允许TreeTwo使用TreeOne作为类型参数,因为TreeOne满足T&lt;:PolyTree [T]的条件。但是,一旦你添加了自我类型注释,Scala本质上会尝试在编译时将TreeTwo中的self /'this'转换为'T'(TreeOne),发现这不是类型安全的,并且拒绝声明TreeTwo错误:
error: illegal inheritance
self-type TreeB does not conform to PolyTree[TreeA]'s selftype TreeA'
我不是最了解或解释这些内容的人,但你可以在O'Reilly的“Scala编程”中从Chapter 12. The Scala Type System获得更多的知识。