我正在尝试实现一个默认值 map,我希望过滤器、映射等在 a上也尽可能DefaultingMap
产生 a 。DefaultingMap
这是我的初始实现:
class DefaultingMap[K, V](defaultValue: => V)
extends mutable.HashMap[K, V]
with mutable.MapLike[K, V, DefaultingMap[K, V]] {
override def empty = new DefaultingMap[K, V](defaultValue)
override def default(key: K): V = {
val result = this.defaultValue
this(key) = result
result
}
}
DefaultingMap
我在使用时得到类型的对象filter
,但在使用时没有map
:
scala> val counter = new DefaultingMap[Char, Int](0)
counter: DefaultingMap[Char,Int] = Map()
scala> for (c <- "ababcbbb") counter(c) += 1
scala> counter.filter{case (k, v) => v > 1}
res1: DefaultingMap[Char,Int] = Map((a,2), (b,5))
scala> counter.map{case (k, v) => (k, v * 2)}
res2: scala.collection.mutable.HashMap[Char,Int] = Map((a,4), (c,2), (b,10))
这两种方法之间的区别似乎是map
需要一个隐含的CanBuildFrom
. 所以我认为我需要有一个implicit def
地方来提供CanBuildFrom
. 我的第一个直觉是做 HashMap 中所做的事情:
object DefaultingMap extends generic.MutableMapFactory[DefaultingMap] {
def empty[K, V]: DefaultingMap[K, V] = // Not possible!
implicit def canBuildFrom[K, V]:
generic.CanBuildFrom[Coll, (K, V), DefaultingMap[K, V]] =
new MapCanBuildFrom[K, V]
}
我相信这会让它编译,但这种方法不起作用,因为不可能定义empty
方法 - 你需要知道defaultValue
应该是什么。如果我可以CanBuildFrom
在类本身中定义,而不是伴随对象,我会没事的,因为defaultValue
那里是可用的。
我怎样才能让它工作?