1

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

  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 uncommented 进行编译时出错的原因与 Spiewak 先生在他的回答中所写的内容有关,即Sets 和Maps 在相关参数中是不变的。

为什么 Scala 的不可变 Set 在其类型上不是协变的?

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

我能够通过写作部分解决这个问题

lazy val freqs:Map[_ <: Any, Int] = 
  (map.toList groupBy (x=>x._2) mapValues(_.size))

但这并不理想,因为密钥类型显示为 Any。我也想说

lazy val uniqueValues = freqs.keySet

并得到 aSet[T]而不是 aSet[Any]

  • 我怎样才能最好地实现freqs上述?
  • keySet其他方法失败时如何返回 Set[T]?
  • 如何Set[T]在地图中获得唯一值?
  • 为什么 _ <: Any 允许它编译?

谢谢!

4

1 回答 1

3

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

不,不是的。map是类型的Map[Int, T],所以虽然它的是类型T,但它的是类型Int。所以keySet这里是类型Set[Int](而不是 Set[T]),这意味着T' 的协方差没有问题。

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

它没有(见上文)

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

鉴于Set它的类型参数是不变的,根本没有办法在Set[T]里面有任何类型的 val Container,除非你将这些 val 标记为private[this],或者使Containerin 保持不变T

我怎样才能最好地实现上述频率?

和上面一样的问题。

为什么 _ <: Any 允许它编译?

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

于 2013-02-20T23:57:13.210 回答