3

我正在尝试编写一个ForwardingMutableMap特性,一个 la Guava's ForwardingMapfor Java

这是我的拳头尝试的样子:

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

第二次尝试:

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

第三次尝试:

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必须实现empty2而不是empty.

这行得通,但有一股黑客的味道。我能做得更好吗?

4

2 回答 2

2

I think what you are looking for is already implemented in Scala standard library, which named MapProxy. Here is the source code :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 回答