我有一个容器类型,它的类型参数是协变的。
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先生在答案中所写的内容有关,Set
和Map
是不变的在相关参数中。
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]
个唯一值?谢谢!
答案 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
处于不变位置