Scala-自定义映射实现的正确类型

Scala-自定义映射实现的正确类型,scala,types,multimap,Scala,Types,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],

我正在尝试实现一个不可变的多重映射(在我的例子中,它也是排序的)。签名如下:

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]]
如您所见,它将大多数操作委托给封装的委托映射。为多重映射功能本身添加了一些额外的方法(类似于)。如果您对完整的源代码感兴趣,请查看

除了
+
方法外,我对当前的实现感到满意:

所需的“+”实现 这会产生类型不匹配错误:
找到:(K,B1)
必需:(K,Set[V])
有办法解决这个问题吗?如果我正确理解
B1
表示
\u>:Set[V]

当前的“+”实现 当前的实现是从一个

这里提供了一个通用实现,并针对特定情况提供了am重载方法。当手动调用该方法时,这可以正常工作,但其他方法,如
++
更新的
等,也依赖于此方法,因此返回错误的集合(
SortedMap
,而不是所需的
SortedMultiMap

好的,如果
B1
是例如
Object
(它满足
Object:>Set[V]
),并且您将
(K,Object)
添加到
委托
,您将得到一个
SortedMap[K,Object]
,显然无法将其转换为
SortedMultiMap
。如果要避免这种情况,有两种选择:

  • 不扩展
    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

  • override def +[B1 >: Set[V]](kv: (K, B1)) = new SortedMultiMap(delegate + kv)
    

    另一种方法是添加从
    SortedMap[K,Set[V]]
    SortedMap[K,V]
    的隐式转换。这样,如果
    B1
    设置为
    Set[V]
    ,结果仍然是
    SortedMap
    ,但您可以自由调用
    SortedMultiMap
    -特定方法,或者在需要
    SortedMultiMap
    的地方使用它。

    第一个选项似乎对我不起作用。我仍然必须实现
    覆盖def+[B1>:设置[V]](kv:(K,B1)):SortedMap[K,B1]=??
    。这与扩展
    SortedMap
    时的问题完全相同。除了不扩展
    SortedMap
    ,我还需要更改签名中的其他内容吗?我认为
    SortedMapLike.+
    返回了
    This
    (类型参数为
    SortedMapLike
    ),但它实际上返回了
    SortedMap
    ,因此第一个解决方案不起作用,抱歉。
    override def +[B1 >: Set[V]](kv: (K, B1)) = new SortedMultiMap(delegate + kv)
    
    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
    }