Двунаправленные ссылки в признаках с одним типом

#scala

#scala

Вопрос:

Я пытаюсь создать признак, который реализует дерево с двунаправленными ссылками таким образом, что когда узел добавляет родительский узел, этот узел добавляется к дочерним элементам родительского узла. Ошибка, которую я получаю ниже, является:

несоответствие типов; найдено :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 
    } 

}
  

Комментарии:

1. Я думаю, что это должно быть = this, а не = tree? Но это не причина ошибки.

2. Предполагалось, что это будет = this … изменен пример.

Ответ №1:

Ошибка возникает из-за того, что тип ‘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]. Однако, как только вы добавляете аннотацию self-type, Scala, по сути, пытается преобразовать self / ‘this’ в TreeTwo в ‘T’ (TreeOne) во время компиляции, обнаруживает, что это не типобезопасно, и отклоняет объявление TreeTwo с ошибкой:

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

Я не лучший специалист в понимании или объяснении этого материала, но вы можете почерпнуть немного больше знаний из главы 12. Система типов Scala в книге О’Рейли «Programming Scala».