#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».