В Scala, как конструктор может ссылаться на объект, который он создает? - PullRequest
3 голосов
/ 01 июля 2010

Я хочу внедрить систему на основе прототипов в Scala.В корне иерархии типов находится узел ROOT, у которого есть прототип, который ссылается на себя.

Следующий код демонстрирует то, что я пытаюсь сделать:

class Node(val prototype: Node) {
    private def this() = this(this)
}

object Node {
    val ROOT = new Node
}

К сожалению,это не компилирует ошибку: «это можно использовать только в классе, объекте или шаблоне».

Аргумент «this» для вызова основного конструктора не принимается.Это звучит разумно, поскольку объект еще не создан.Однако, поскольку прототип является неизменяемым, я не могу установить его на нуль и определить его впоследствии.

Есть предложения о том, как сделать это правильно в Scala?

Я использую Scala-2.8.0RC7.

Ответы [ 3 ]

7 голосов
/ 01 июля 2010

Похоже, у вас есть два типа вещей (корневые и простые узлы). Как насчет этого?

trait Node { def prototype: Node }

class RootNode extends Node { def prototype = this }

class SimpleNode(val prototype: Node) extends Node

В REPL вы можете сделать это тогда:

scala> val rootNode = new RootNode
rootNode: RootNode = RootNode@191dd1d

scala> val n1 = new SimpleNode(rootNode)
n1: SimpleNode = SimpleNode@30e4a7

scala> val n2 = new SimpleNode(n1)
n2: SimpleNode = SimpleNode@3a0589

scala> n2.prototype.prototype
res0: Node = RootNode@191dd1d

Я не знаю, если это то, что вы ищете.

2 голосов
/ 01 июля 2010

Вы также можете сделать следующее.Возможно, это не самый идиоматичный код Scala, но он короткий и, я думаю, он отвечает на ваш вопрос.

class Node(prot: Option[Node] = None) { def prototype = prot getOrElse this }
1 голос
/ 01 июля 2010

Я не совсем понимаю, как вы можете это сделать - как вы можете создать построенный экземпляр корневого узла, если вам нужно, чтобы уже существовало при его создании?Таким образом, в этом виновата ваша модель проблемной области, а не Scala (или любого другого языка в этом отношении)

Конечно, корневой узел может иметь прототип null или (более идиоматический scala)Option прототип?

class Node private[mypackage](val prototype : Option[Node]) {
  private def this() = this(None)
  private def this(ptype : Node) = this(Some(ptype)) //Public c-tor
}

object Node extends (Node => Node) {
  val Root = new Node
  def apply(ptype : Node) = new Node(ptype)
}
...