如何在 Scala 中创建循环引用?

How to create a circular reference in Scala?

给出以下代码示例

case class Thing(
    value: String,
    parents: Seq[Thing],
    children: Seq[Thing],
  )

val x = Thing(
    value = "foo",
    parents = Seq(y),
    children = Seq(),
)

val y = Thing(
    value = "bar",
    parents = Seq(x),
    children = Seq(),
)

由于在创建 x 时未初始化 y 而出错,是否有任何方法可以执行此“循环引用”而不使用辅助数据结构(例如哈希映射)来手动创建指向每个对象的指针?

修复编译代码和运行时异常的一种方法是:

class Thing(
  _value: => String,
  _parents: => Seq[Thing],
  _children: => Seq[Thing]
) {
  lazy val value = _value
  lazy val parents = _parents
  lazy val children = _children
}

object Thing {
  def apply(
      value: => String,
      parents: => Seq[Thing],
      children: => Seq[Thing]
  ): Thing = {
    new Thing(value, parents, children)
  }
}

val x: Thing = Thing(
  value = "foo",
  parents = Seq(y),
  children = Seq()
)

val y: Thing = Thing(
  value = "bar",
  parents = Seq(x),
  children = Seq()
)

Thing class 中使用的字段必须延迟求值,但由于 Scala prohibits 使用 call-by-name 作为 public class 参数,我存储了它们在私人 class 参数中,并使它们 public 可以通过 public lazy vals.

访问