我正在尝试写一个ForwardingMutableMap
特征,一个Guava's ForwardingMap
for 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
。
这可以起作用,但闻起来有点黑客。我可以做得更好吗?
答案 0 :(得分: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)
答案 1 :(得分: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)
}