デフォルト値のマップを実装しようとしていますが、フィルターやマップなどを可能な限りDefaultingMap
生成するようにしたいと思います。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))
これらの2つの方法の違い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
です。
どうすればこれを機能させることができますか?