2017-07-27 21 views
1

私が書くしようとするでしょう、エンドユーザー向けの部分は次のようになります。小さな図書館で

理想的
case class Box(is: Item*) 
case class Item(data: Int) 

Box(Item(0), Item(1)) 

、しかし、各アイテムはここで知っておくべきそれはボックスです:

case class Item(data: Int, box: Box) 

不変のケースクラスとこの双方向接続を確立する方法はありますか?怠惰と暗黙を使用して

val i = Item(0, None) // requires Option :(
val box = Box(i) 
i.box = Some(box) // requires var in Item :(

...しかし、解決策を考え出すことができませんでした:私は...このような何かを避けるために

val box = Box() 
val i = Item(0, box) 
box.add(i) // requires var in Box :(

またはこれを試してみました。まったく可能ですか?

次の質問から、pass-by-name + lazyは役に立ちますが、それでもボックスは明示的に渡される必要があることがわかりました。[Scala: circular references in immutable data types?

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)) 

マイナス面:目標は使用することができ:)

答えて

0

を必要なだけの魔法の舞台裏で、できるだけシンプル/スリムとして、エンドユーザー向けの一部にすることであるあなたは、このような何かを行うことができますBoxコンストラクタはちょっと変わっていますし、ItemはItemオブジェクトのapplyメソッドの変更に依存しているので、もはやcaseクラスではありません。しかしこれは、オブジェクトを作成するための全く同じ構文を取得し、循環参照を作成します。

+1

問題の1つは、 'Box(Item(0))== Box(Item(0))== false'です。もう1つは 'Box(Item(0))。toString == Box(WrappedArray())'です。未適用は機能しません。あなたは、ケースクラスを廃止し、これを機能させるために明示的にすべての機能を実装する必要があります。 – Dima

+0

私は同意する、このアプローチの欠点はたくさんある。 'Item'に' var'を使うのと同じように、それほど悪くないでしょう。元の質問は具体的にそれを不可能にする方法について具体的に尋ねました。 –

+0

大文字小文字のクラスを使用しないことは良い考えです。 – Dima

関連する問題