2

ObservableMap と、受信したイベントを出力するだけのサブスクライバーを作成します (ここから取得)。

class MyMap extends HashMap[Int,Int] with ObservableMap[Int,Int]

class MySub extends Subscriber[Message[(Int,Int)] with Undoable, ObservableMap[Int, Int]] {
  def notify(pub: ObservableMap[Int, Int], evt: Message[(Int, Int)] with Undoable) { 
    println(evt)
  }
}

val map = new MyMap
map.subscribe(new MySub)

+=++=、および-=を使用すると、期待どおりに機能します。

scala> map += 1 -> 1
Include(NoLo,(1,1))
res5: map.type = Map(1 -> 1)

scala> map ++= Map(2 -> 4, 3 -> 9)
Include(NoLo,(3,9))
Include(NoLo,(2,4))
res6: map.type = Map(3 -> 9, 1 -> 1, 2 -> 4)

scala> map -= 1
Remove(NoLo,(1,1))
res7: map.type = Map(3 -> 9, 2 -> 4)

しかし、更新は機能しません:

scala> map(4) = 16

scala> map
res9: MyMap = Map(3 -> 9, 4 -> 16, 2 -> 4)

なんで?ObservableMap が+=-=、およびclearをオーバーライドしているようです。++=updateの両方が+=の観点から実装されているように見えますが(Growable と MapLike によって)、一方では機能するのに他方では機能しないのはなぜですか?

4

1 に答える 1

3

HashMap の変更可能なバージョンは update を呼び出します。これは put を呼び出しますが、これは += を呼び出さないため、監視可能な += メソッドは呼び出されません。私はscala 2.9.1を使用していますが、これは2.8でも同じはずです。

HashMap から:

  override def put(key: A, value: B): Option[B] = {
    val e = findEntry(key)
    if (e == null) { addEntry(new Entry(key, value)); None }
    else { val v = e.value; e.value = value; Some(v) }
  }

  override def update(key: A, value: B): Unit = put(key, value)

  def += (kv: (A, B)): this.type = { 
    val e = findEntry(kv._1)
    if (e == null) addEntry(new Entry(kv._1, kv._2))
    else e.value = kv._2
    this
  }
于 2012-05-31T21:26:56.350 に答える