在我要尝试编写的小型库中,最终面向用户的部分如下所示:
case class Box(is: Item*)
case class Item(data: Int)
Box(Item(0), Item(1))
但理想情况下,每个项目都应该知道它在哪个框中:
case class Item(data: Int, box: Box)
有没有办法与不可变的案例类建立这种双向连接?我试图避免这样的事情......
val box = Box()
val i = Item(0, box)
box.add(i) // requires var in Box :(
或者这个:
val i = Item(0, None) // requires Option :(
val box = Box(i)
i.box = Some(box) // requires var in Item :(
...使用懒惰和暗示,但无法提出解决方案。有可能吗?
从下面的问题中,我了解到pass-by-name + lazy可能很有用,但仍然需要明确传递该框:[Scala: circular references in immutable data types?。我们的目标是尽可能使面向最终用户的部分变得简单/纤薄,在幕后可以使用所需的魔法:)
答案 0 :(得分:0)
你可以这样做:
case class Box(is: (Box => Item)*) {
lazy val items = is.map(_(this))
}
class Item(val data: Int, val box: Box)
object Item {
def apply(data: Int)(box: Box): Item = new Item(data, box)
}
val b = new Box(Item(0), Item(1))
下限是Box构造函数有点奇怪,而Item不再是case类,因为它依赖于更改Item对象的apply
方法。但这会为您创建用于创建对象的完全相同的语法,并创建循环引用。