3

私は、Java用のlaGuavaのForwardingMutableMap特性を書き込もうとしています。ForwardingMap

これが私の最初の試みがどのように見えたかです:

trait ForwardingMutableMap[K, V, +Self <: mutable.MapLike[K, V, Self] with mutable.Map[K, V]] 
    extends mutable.Map[K, V] 
    with mutable.MapLike[K, V, Self] { this: Self =>

  protected val delegate: mutable.Map[K, V]

  def get(key: K): Option[V] = delegate.get(key)

  def iterator: Iterator[(K, V)] = delegate.iterator

  def -=(key: K): this.type = {
    delegate -= key
    this
  }

  def +=(kv: (K, V)): this.type = {
    delegate += kv
    this
  }
}

これにより、エラーが発生します。

error: overriding method empty in trait MapLike of type => Self;
 method empty in trait Map of type => scala.collection.mutable.Map[K,V] has incompatible type
       trait ForwardingMutableMap[K, V, +Self <: mutable.MapLike[K, V, Self] with mutable.Map[K, V]] 

2回目の試行:

trait ForwardingMutableMap[K, V, +Self <: mutable.MapLike[K, V, Self] with mutable.Map[K, V]] 
    extends mutable.Map[K, V] 
    with mutable.MapLike[K, V, Self] { this: Self =>

  def empty: Self

  protected val delegate: mutable.Map[K, V]

  def get(key: K): Option[V] = delegate.get(key)

  def iterator: Iterator[(K, V)] = delegate.iterator

  def -=(key: K): this.type = {
    delegate -= key
    this
  }

  def +=(kv: (K, V)): this.type = {
    delegate += kv
    this
  }
}

エラー:

error: overriding method empty in trait ForwardingMutableMap of type => ForwardingMutableMap.this.Self;
 method empty in trait Map of type => scala.collection.mutable.Map[K,V] has incompatible type;
 (Note that method empty in trait ForwardingMutableMap of type => ForwardingMutableMap.this.Self is abstract,
  and is therefore overridden by concrete method empty in trait Map of type => scala.collection.mutable.Map[K,V])
       trait ForwardingMutableMap[K, V, +Self <: mutable.MapLike[K, V, Self] with mutable.Map[K, V]] 

3回目の試行:

trait ForwardingMutableMap[K, V, +Self <: mutable.MapLike[K, V, Self] with mutable.Map[K, V]] 
    extends mutable.Map[K, V] 
    with mutable.MapLike[K, V, Self] { this: Self =>

  override def empty: Self = empty2

  def empty2: Self

  protected val delegate: mutable.Map[K, V]

  def get(key: K): Option[V] = delegate.get(key)

  def iterator: Iterator[(K, V)] = delegate.iterator

  def -=(key: K): this.type = {
    delegate -= key
    this
  }

  def +=(kv: (K, V)): this.type = {
    delegate += kv
    this
  }
}

タイプミキシングは、の代わりにForwardingMutableMap実装する必要があります。empty2empty

これは機能しますが、ハックのにおいがします。もっと上手くできますか?

4

2 に答える 2

2

あなたが探しているものは、という名前の Scala 標準ライブラリに既に実装されていると思いますMapProxy。ソースコードは次のとおりです: src

scala> new mutable.MapProxy[Int, Int]{ override val self = HashMap.empty[Int, Int] }
res1: scala.collection.mutable.MapProxy[Int,Int]{val self: scala.collection.mutable.HashMap[Int,Int]} = Map()

scala> res1 += ((1,2))
res2: <refinement>.type = Map(1 -> 2)

scala> res1
res3: scala.collection.mutable.MapProxy[Int,Int]{val self: scala.collection.mutable.HashMap[Int,Int]} = Map(1 -> 2)
于 2013-02-25T07:12:40.470 に答える
1

このようなものはどうですか?

trait ForwardingMutableMap[K, V]
  extends Map[K, V] with MapLike[K, V, ForwardingMutableMap[K, V]] {

  override def empty = ForwardingMutableMap.empty

  protected val delegate: Map[K, V]

  def get(key: K): Option[V] = delegate.get(key)

  def iterator: Iterator[(K, V)] = delegate.iterator

  def -=(key: K): this.type = {
    delegate -= key
    this
  }

  def +=(kv: (K, V)): this.type = {
    delegate += kv
    this
  }
}

object ForwardingMutableMap {
  def empty[K, V]:ForwardingMutableMap[K, V] = new ForwardingMutableMap[K, V] {
    protected val delegate = Map.empty[K, V]
  }
}

編集

それを具象にしたくないが、MapLike(複数の具体的な実装を持つことができる)に似た特性にしたい場合は、次のように定義できます。

trait ForwardingMutableMap[K, V, Self <: ForwardingMutableMap[K, V, Self] with Map[K, V]]
  extends MapLike[K, V, Self] { 

  protected val delegate: Map[K, V]

  // ...
}

そして、このように使用します

class MyMap[K, V](val delegate:Map[K, V]) extends Map[K, V] with ForwardingMutableMap[K, V, MyMap[K, V]] {
  override def empty = MyMap.empty
}

object MyMap {
  def empty[K, V] = new MyMap[K, V](Map.empty) 
}
于 2013-02-24T15:44:00.137 に答える