在Scala中,构造函数如何引用它正在创建的对象?

时间:2010-07-01 11:50:55

标签: scala scala-2.8

我想在Scala中实现基于原型的系统。在类型层次结构的根部是ROOT节点,它具有引用自身的原型。

以下代码演示了我正在尝试做的事情:

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

object Node {
    val ROOT = new Node
}

不幸的是,这不会编译错误:“这只能在类,对象或模板中使用”。

不接受调用主构造函数的参数“this”。这听起来很合理,因为尚未创建对象。但是,由于原型是不可变的,我不能将它设置为null并在之后定义它。

有关如何在Scala中正确执行此操作的任何建议吗?

我正在使用Scala-2.8.0RC7。

3 个答案:

答案 0 :(得分:7)

对于这看起来你有两种东西(根节点和简单节点)这个怎么样?

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

我不知道,如果这就是你要找的东西。

答案 1 :(得分:2)

您还可以执行以下操作。也许它不是最惯用的Scala代码,但它很短,我认为它可以回答你的问题。

class Node(prot: Option[Node] = None) { def prototype = prot getOrElse this }

答案 2 :(得分:1)

我不太清楚你怎么能这样做 - 如果在创建根节点时需要已经存在,你怎么能拥有根节点的构造实例?所以这里有问题的是你对问题域的建模,而不是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)
}