Ste*_*eve 5 scala scala-collections
我正在尝试实现默认值映射,并且我希望过滤器,映射等等,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
}
}
Run Code Online (Sandbox Code Playgroud)
我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))
Run Code Online (Sandbox Code Playgroud)
这两种方法之间的区别似乎是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]
}
Run Code Online (Sandbox Code Playgroud)
我相信这会让它编译,但这种方法不起作用,因为无法定义empty方法 - 你需要知道它defaultValue应该是什么.如果我可以CanBuildFrom在类本身中定义,而不是伴随对象,我会没事的,因为defaultValue那里有可用的.
我怎样才能让它发挥作用?
可变映射Builder在Scala中,因此MapFactory默认情况下采用所讨论类型的空映射来获取构建器.
如果您有自定义地图构建规则,您可以做的一件事就是定义类似于的自定义工厂collection.generic.MapFactory.你必须以类似的方式定义它,但是让empty方法和newBuilder方法都需要额外的参数defaultValue.
有些事情(如果您在建议的其他链接中阅读有关Scala 2.8集合API的更多信息,您会发现您不必为地图实现通用伴随对象):
import collection._
class DefaultingMap[K, V](val defaultValue: V)
extends mutable.HashMap[K, V]
with mutable.MapLike[K, V, DefaultingMap[K, V]] {
override def empty = new DefaultingMap(defaultValue)
}
object DefaultingMap {
def newBuilder[K, V](d: V): DefaultingMap[K, V] = new DefaultingMap[K, V](d)
implicit def canBuildFrom[K, V] =
new generic.CanBuildFrom[DefaultingMap[K, V], (K, V), DefaultingMap[K, V]] {
def apply(from: DefaultingMap[K, V]) = newBuilder[K, V](from.defaultValue)
def apply() = error("unsupported default apply")
}
}
object Main {
def main(args: Array[String]) {
println((new DefaultingMap[Int, Int](5)).defaultValue)
println(((new DefaultingMap[Int, Int](5)).map(x => x)).defaultValue)
}
}
Run Code Online (Sandbox Code Playgroud)
打印:
$ scalac defaulting.scala
$ scala Main
5
5
Run Code Online (Sandbox Code Playgroud)
我承认,这仍然没有解决无参数问题apply.
| 归档时间: |
|
| 查看次数: |
1708 次 |
| 最近记录: |