例如
trait AA[+X[n], +Y] {
def x: X[Y] // [Error]: covariant type Y occurs in invariant position in type => X[Y] of method x
}
这似乎是错误的信息,因为 X[Y] 可以很容易地证明是协变的:
如果 Y1 >:> Y2, +X1[n] >:> +X2[n] 对于所有 n,则:
Y1 >:> Y2
(X2 的协方差)=> X2[Y1] >:> X2[Y2]
(X1[Y1] >:> X2[Y1]) => X1[Y1] >:> X2[Y2]
什么可能导致此错误消息?
你又少了一个
+
。正确的是
trait AA[+X[+n], +Y] {
def x: X[Y]
}
那么类型
X
将是协变的(相对于其类型参数 n
)和位置
def x: X[...]
// ^^^ <- this position
将是协变的,你将能够在这个位置使用协变类型参数
Y
。
相反,您声明了不变类型
X
(w.r.t.n
)并尝试在不变位置使用协变类型参数Y
。
有不同的概念:
协变/逆变/不变类型参数(
+T
, -T
, T
)
协变/逆变/不变类型,即类型构造函数,关于它的类型参数(
T1 <: T2 => A[T1] <: A[T2]
,T1 <: T2 => A[T1] >: A[T2]
,或没有这些)
协变/逆变/不变位置根据规则https://scala-lang.org/files/archive/spec/2.13/04-basic-declarations-and-definitions.html#variance-annotations
+X[n]
是 AA
的协变类型参数,但相对于类型参数 n
. 是不变类型