我对下面的类型检查器的严格性感到有些困惑——似乎不变量 T
Inv[T]
的位置在 Variantish
内也是不变的的参数列表:
scala> class Inv[T]
defined class Inv
scala> class Variantish[+T, +TVar <: Inv[T]]
<console>:12: error: covariant type T occurs in invariant position in type <: Inv[T] of type TVar
class Variantish[+T, +TVar <: Inv[T]]
^
变体类型通常可以合法地出现在看起来像不变的参数列表位置,例如具有对象保护的可见性:
class Variantish[+T](protected[this] var v: Inv[T])
似乎以下内容也是类型安全的:
class Variantish[+T, +TVar <: Inv[T]](protected[this] var v: TVar)
上面提到的检查需要这么严格吗?
最佳答案
来自语言 specification (强调我的),关于一致性(即 T'
是 T
的父类(super class)型):
Type constructors
T
andT′
follow a similar discipline. We characterizeT
andT′
by their type parameter clauses[a1,…,an]
and[a′1,…,a′n]
, where anai
ora′i
may include a variance annotation, a higher-order type parameter clause, and bounds. Then,T
conforms toT′
if any list[t1,…,tn]
-- with declared variances, bounds and higher-order type parameter clauses -- of valid type arguments forT′
is also a valid list of type arguments forT
andT[t1,…,tn]<:T′[t1,…,tn]
.
这真的很难理解(恕我直言),但我相信这意味着对于
Variantish
在 T
中协变,你必须能够写Variantish[Dog, TVar] <: Variantish[Animal, TVar]
为 任何
TVar
其中Variantish[Animal, TVar]
说得通。但这对其中一些人来说甚至没有意义(更不用说有任何真值了)TVar
,例如 Inv[Animal]
.这就是为什么在那个地方是被禁止的。
关于scala - 为什么所有不变的泛型类位置在 Scala 的类型参数列表中都是不变的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43259984/