为什么Scala的不可变集的类型不协变? [英] Why is Scala's immutable Set not covariant in its type?
问题描述
编辑:根据原始答案重新编写该问题
scala.collection.immutable.Set
类的类型参数不是协变的。为什么是这样?
import scala.collection.immutable._
def foo(s:Set [CharSequence]) :单位= {
println(s)
}
def bar():单位= {
val s:Set [String] = Set( Hello ,世界);
foo; //不会编译,无论是否在$ val声明
中明确声明了类型
}
Set
的set参数是不变的,这是因为set作为函数的概念。以下签名应稍作澄清:
特征集[A]扩展(A =>布尔值){
def apply(e:A):布尔值
}
如果 Set
在 A
中是协变的,因此 apply
方法将无法采用参数由于函数的差异性,请键入 A
。 Set
在 A
中可能是 contravariant ,但是当您要做这样的事情:
def元素:可迭代[A]
$简而言之,最好的解决方案是即使对于不可变的数据结构,也要保持不变。您会注意到,
immutable.Map
的类型参数之一也是不变的。EDIT: Re-written this question based on original answer
The
scala.collection.immutable.Set
class is not covariant in its type parameter. Why is this?import scala.collection.immutable._ def foo(s: Set[CharSequence]): Unit = { println(s) } def bar(): Unit = { val s: Set[String] = Set("Hello", "World"); foo(s); //DOES NOT COMPILE, regardless of whether type is declared //explicitly in the val s declaration }
解决方案
Set
is invariant in its type parameter because of the concept behind sets as functions. The following signatures should clarify things slightly:trait Set[A] extends (A=>Boolean) { def apply(e: A): Boolean }
If
Set
were covariant inA
, theapply
method would be unable to take a parameter of typeA
due to the contravariance of functions.Set
could potentially be contravariant inA
, but this too causes issues when you want to do things like this:def elements: Iterable[A]
In short, the best solution is to keep things invariant, even for the immutable data structure. You'll notice that
immutable.Map
is also invariant in one of its type parameters.这篇关于为什么Scala的不可变集的类型不协变?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!