问题描述
编辑:根据原始答案重写此问题
EDIT: Re-written this question based on original answer
scala.collection.immutable.Set
类的类型参数不是协变的.为什么是这样?
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
的类型参数是不变的,因为集合背后的概念是函数.以下签名应该稍微澄清一下:
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
}
如果 Set
在 A
中是协变的,则 apply
方法将无法采用 A
由于函数的逆变性.Set
可能在 A
中是 逆变,但是当您想要执行以下操作时,这也会导致问题:
If Set
were covariant in A
, the apply
method would be unable to take a parameter of type A
due to the contravariance of functions. Set
could potentially be contravariant in A
, but this too causes issues when you want to do things like this:
def elements: Iterable[A]
简而言之,最好的解决方案是保持事物不变,即使对于不可变的数据结构也是如此.您会注意到 immutable.Map
在其类型参数之一中也是不变的.
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 的不可变 Set 在其类型上不是协变的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!