我正在尝试实现一个不可变的MultiMap(在我的例子中它也是排序的)。签名如下:
class SortedMultiMap[K,V] private (private val delegate: SortedMap[K, Set[V]])
(implicit ord: Ordering[K])
extends SortedMap[K, Set[V]]
with SortedMapLike[K, Set[V], SortedMultiMap[K,V]]
如您所见,它将大多数操作委托给封装的委托映射。为MultiMap功能本身添加了一些额外的方法(类似于scala.collection.mutable.MultiMap)。如果您对完整的源代码感兴趣,请查看gist。
除了+
方法之外,我对我当前的实现感到满意:
override def +[B1 >: Set[V]](kv: (K, B1)) = new SortedMultiMap(delegate + kv)
这会导致类型不匹配错误:found: (K, B1)
required: (K, Set[V])
。 有没有办法解决这个问题?如果我理解正确B1
代表_ >: Set[V]
。
目前的实施取自similar question about custom map implementation
override def +[B1 >: Set[V]](kv: (K, B1)): SortedMap[K, B1] = delegate + kv // general case
def +(kv: (K,Set[V])): SortedMultiMap[K, V] = new SortedMultiMap(delegate + kv) // specific case
这里提供了一般实现,并为特定情况提供了重载方法。这在手动调用方法时工作正常,但其他方法(如++
,updated
等)也依赖于此方法,从而返回错误的集合(SortedMap
而不是所需的{{ 1}})。
答案 0 :(得分:1)
override def +[B1 >: Set[V]](kv: (K, B1)) = new SortedMultiMap(delegate + kv)
好吧,如果B1
是Object
(满足Object :> Set[V]
),然后将(K, Object)
添加到delegate
,您将获得SortedMap[K, Object]
,显然无法将其变为SortedMultiMap
{1}}。如果您想避免这种情况,您有两种选择:
不展开SortedMap
(您仍可以展开SortedMapLike
)(不起作用,请参阅评论)。
匹配值的类型:
override def +[B1 >: Set[V]](kv: (K, B1)): SortedMap[K, B1] = kv._2 match {
// may need some massaging to persuade the compiler
case v: Set[a] => new SortedMultiMap(delegate + (kv._1, v))
case _ => delegate + kv
}
请注意,在这种情况下,静态返回类型始终为SortedMap
。
另一种方法是添加从SortedMap[K, Set[V]]
到SortedMultiMap[K,V]
的隐式转换。这种方式如果B1
为Set[V]
,则结果仍为SortedMap
,但您可以自由调用SortedMultiMap
- 具体方法,或以其他方式使用SortedMultiMap
预期