2011-05-10 19 views
2

我想创建一个实现具有bidrectional链接的树的特征,以便在节点添加父节点时将该节点添加到父节点的子节点。我得到下面的错误是:具有单一类型特征的双向链接

类型不匹配;发现: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

我认为这应该是+ =这,而不是+ =树?但这不是错误的原因。 – 2011-05-10 03:04:12

+0

它应该是+ =这...改变了这个例子。 – user465342 2011-05-10 03:54:33

回答

4

发生错误的原因是'parent._children'的类型是'T',而'this'的类型是'PolyTree [T]',它们是Scala中的不同类型。

您可以通过在特征的顶部插入下面的自我类型的注释修复错误:

self: T => 

这是必要的,因为没有它,以下是合法的代码:

class TreeOne extends PolyTree[TreeOne] 
class TreeTwo extends PolyTree[TreeOne] 

TreeTwo允许使用TreeOne作为类型参数,因为TreeOne满足T <:PolyTree [T]的条件。但是,一旦添加了自我类型注释,Scala本质上会尝试在编译时在TreeTwo中将自己/'this'转换为'T'(TreeOne),发现它不是类型安全的,并拒绝TreeTwo出现错误:

error: illegal inheritance 
self-type TreeB does not conform to PolyTree[TreeA]'s selftype TreeA' 

我不是在理解或解释这个东西是最好的,但你可以从Chapter 12. The Scala Type System在O'Reilly的“编程斯卡拉”争取更多的知识。