scala - 为什么所有不变的泛型类位置在 Scala 的类型参数列表中都是不变的?

标签 scala generics invariance

我对下面的类型检查器的严格性感到有些困惑——似乎不变量 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 and T′ follow a similar discipline. We characterize T and T′ by their type parameter clauses [a1,…,an] and [a′1,…,a′n], where an ai or a′i may include a variance annotation, a higher-order type parameter clause, and bounds. Then, T conforms to T′ if any list [t1,…,tn] -- with declared variances, bounds and higher-order type parameter clauses -- of valid type arguments for T′ is also a valid list of type arguments for T and T[t1,…,tn]<:T′[t1,…,tn].



这真的很难理解(恕我直言),但我相信这意味着对于 VariantishT 中协变,你必须能够写
Variantish[Dog, TVar] <: Variantish[Animal, TVar]

任何 TVar其中Variantish[Animal, TVar]说得通。但这对其中一些人来说甚至没有意义(更不用说有任何真值了)TVar ,例如 Inv[Animal] .这就是为什么在那个地方是被禁止的。

关于scala - 为什么所有不变的泛型类位置在 Scala 的类型参数列表中都是不变的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43259984/

相关文章:

c# - 如何仅使用基类中的代码返回派生类?

generics - 使用泛型函数制作盒装特征会返回错误

java - 如何在 C# 中创建对象时省略泛型参数?

c# - 对 "Already defines a member with the same parameter types"错误感到困惑

image - Scala 检测 Array[Byte] 图像的 mimetype

scala - 如何在图中找到每个顶点的度-RDD转换?

generics - Kotlin 中的方差/协方差泛型

java - 如何使用scala映射模型类中的多种类型?

java - 我无法连接到 docker 中的 rabbitmq 服务器