Scala: класс, объявляющий себя переменной - PullRequest
1 голос
/ 24 мая 2010

Я пытаюсь создать бинарное дерево в scala, и мне нужно создать метод для него, поэтому я пытаюсь создать функции внутри класса, которые имеют дело с потомками и родителями. Я хочу сделать родительский объект деревом, чтобы я мог рекурсивно вызвать его в другой функции с именем getPath, но не могу создать дерево внутри класса Tree. это код:

case class Tree[+T](value: T, left: Option[Tree[T]], right: Option[Tree[T]]) {
   var parent: Tree[T] = null

   //method for setting the parent of tree.
   //this method returns the parent TREE instead of the parent value
   //so if you want to use it to find the value, you need to get the parent.value
   def setParent(tree: Tree[T]) {
 parent = tree
   }

   //method for returning the parent
   //the parent is a tree so you have to .value it to get the root
   def getParent(): Tree[T] = parent

   //setting parents of left child and right child if they are not empty trees
   if(left != None) {
      left.get.setParent(this)
   }
   if(right != None) {
      right.get.setParent(this)
   }
}

def getPath[T](tree: Tree[T]):List[T] = {
   if(tree.getParent == null) List(tree.value)
   List(tree.value)++getPath(tree.getParent())
}

Я могу установить для T значение Any, и оно будет работать, но тогда я не могу рекурсивно вызвать его, если вы это сделаете. Кто-нибудь может мне помочь или есть другой способ получить родителя дерева?

1 Ответ

5 голосов
/ 24 мая 2010

Немного почистив твой код, добираюсь до:

case class Tree[+T](value: T, left: Option[Tree[T]], right: Option[Tree[T]]) {
  @reflect.BeanProperty   
  var parent: Tree[T] = null

  //setting parents of left child and right child if they are not empty trees
  Seq(left, right).flatten.foreach(_.setParent(this))
}

object Tree {
  def getPath[T](tree: Tree[T]):List[T] = List(tree.value) ++
    (if(tree.getParent == null) 
      Nil
    else
      getPath(tree.getParent()))
}

Это не скомпилируется с:

tree-parent.scala: 1: ошибка: ковариантный тип T возникает в контравариантной позиции в типе Tree [T] параметра родительского установщика _ =

Параметр типа T появляется в типах, созданных (метод получения для родителя) и использованных (метод установки для родителя) этим интерфейсом. Соответственно, он должен быть инвариантным:

case class Tree[T]
...