返回带有协变类型的immutable.Map

时间:2013-02-20 23:27:47

标签: scala collections types covariance

我有一个容器类型,它的类型参数是协变的。

  class Container[+T](val map: Map[Int, T] = Map.empty[Int, T]){
    def add[B >: T](i: Int, b: B) = new Container(map + (i->b))
//    lazy val freqs = (map.toList groupBy (x=>x._2) mapValues(_.size))
//    lazy val uniq = map.toSet
      lazy val keySet = map.keySet
  }

我在想我尝试使用freqs或uniq编译时出错的原因与Spiewak先生在答案中所写的内容有关,SetMap是不变的在相关参数中。

Why is Scala's immutable Set not covariant in its type?

然而,我有点惊讶地发现包含keySet并没有问题,而keySet确实返回了类型为T的Set

我能够通过编写

来部分解决这个问题
lazy val freqs:Map[_ <: Any, Int] = 
  (map.toList groupBy (x=>x._2) mapValues(_.size))

但这不太理想,因为密钥类型是Any。我想也能说

lazy val uniqueValues = freqs.keySet

获得Set[T]而不是Set[Any]

  • 如何最好地实施上述freqs
  • 当其他方法失败时,keySet如何返回Set [T]?
  • 如何在地图中获得Set[T]个唯一值?
  • 为什么_&lt;:任何允许这个编译?

谢谢!

1 个答案:

答案 0 :(得分:3)

  

然而,我有点惊讶地发现包含keySet并没有问题,而keySet确实返回了一个类型为T的Set

不,不。 map的类型为Map[Int, T],因此其的类型为T,其的类型为Int }。因此keySet类型为Set[Int](并且 Set[T]),这意味着T的协方差没有问题。

  

当其他方法失败时,keySet如何返回Set [T]?

它没有(见上文)

  

如何在Map中获得Set [T]的唯一值?

鉴于Set在其类型参数中是不变的,除非您将这些值标记为Set[T],否则根本无法在Container中包含任何类型为private[this]的val。 },或在Container中使T保持不变。

  

如何最好地实现上述频率?

与上述问题相同。

  

为什么_&lt ;:任何允许这个编译?

因为在明确说明freq类型为Map[_ <: Any, Int]时,您删除了对T的依赖,因此就方差而言没有任何问题。如果您没有明确说明freq的类型,则scala(正确)将类型推断为Map[T, Int],其中确实依赖于T处于不变位置