在这种情况下,有必要拥有与Guava MultiSet非常相似的东西。我已经使用了scala MultiMap,将其混合为一个特性和。我试着为MultiSet做点什么。
trait MultiSet[A] extends mutable.Map[A, Int] {
def setCount(e:A, count:Int):Unit = {
this.update(e, this.getCount(e) + count)
}
def getCount(e:A): Int = this.getOrElse(e, 0)
}
我用它作为:
scala> val degree = new mutable.HashMap[String, Int] with MultiSet[String, Int]
scala> degree.getCount("a")
res0: Int = 0
scala> degree.setCount("a", 1)
scala> degree.setCount("a", 2)
scala> degree.getCount("a")
res1: Int = 3
我想做一个额外的步骤(可能没有必要,Int应该足够了),我写了这样的:
trait MultiSet[A, T] extends mutable.Map[A, T] {
def setCount(e:A, count:T)(implicit num: Numeric[T]):Unit = {
this.update(e, num.plus(this.getCount(e), count))
}
def getCount(e:A)(implicit num: Numeric[T]): T = this.getOrElse(e, num.zero)
}
我的问题是,有一种方法可以对T执行强制,告诉编译器应该存在该类型的Numeric[T]?
带配套对象的解决方案
trait MultiSet[A, T] extends mutable.Map[A, T] {
protected def numeric: Numeric[T]
def setCount(e:A, count:T):Unit = {
this.update(e, numeric.plus(this.getCount(e), count))
}
def getCount(e:A): T = this.getOrElse(e, numeric.zero)
}
object MultiSet {
def empty[A, T: Numeric] = new mutable.HashMap[A, T] with MultiSet[A, T] {
val numeric: Numeric[T] = implicitly[Numeric[T]]
}
}
val degreeInt = MultiSet.empty[String, Int] // Ok
val degreeString = MultiSet.empty[String, String] // Compile Error