Given the following code example
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(),
)
errors out because y is not initialized when creating x, is there any way of performing this "circular referencing" without using a secondary data structure such as a hash map to manually create pointers to each object?
CodePudding user response:
One way to fix the compile code and the runtime exception is:
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()
)
Fields used in Thing
class must be evaluated lazily but since Scala prohibits using call-by-name for public class parameters I stored them in private class parameters and made them publicly accessible through public lazy val
s.