引用容器中项目的容器

时间:2017-07-27 21:06:58

标签: scala

在我要尝试编写的小型库中,最终面向用户的部分如下所示:

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?。我们的目标是尽可能使面向最终用户的部分变得简单/纤薄,在幕后可以使用所需的魔法:)

1 个答案:

答案 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方法。但这会为您创建用于创建对象的完全相同的语法,并创建循环引用。