con*_*cat 5 generics scala 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]]
^
Run Code Online (Sandbox Code Playgroud)
变体类型通常可以合法地出现在不变的参数列表位置,例如具有对象保护的可见性:
class Variantish[+T](protected[this] var v: Inv[T])
Run Code Online (Sandbox Code Playgroud)
并且似乎以下类似于类型安全:
class Variantish[+T, +TVar <: Inv[T]](protected[this] var v: TVar)
Run Code Online (Sandbox Code Playgroud)
需要上面提到的检查是如此严格?
从语言规范(强调我的),关于一致性(即T\'是 的超类型T):
\n\n\n输入构造函数
\nT并T\xe2\x80\xb2遵循类似的规则。我们通过它们的类型参数子句和来T表征和,其中或可以包括方差注释、高阶类型参数子句和界限。然后,符合 的有效类型参数的任何列表(带有声明的方差、边界和高阶类型参数子句)也是和的类型参数的有效列表。T\xe2\x80\xb2[a1,\xe2\x80\xa6,an][a\xe2\x80\xb21,\xe2\x80\xa6,a\xe2\x80\xb2n]aia\xe2\x80\xb2iTT\xe2\x80\xb2[t1,\xe2\x80\xa6,tn]T\xe2\x80\xb2TT[t1,\xe2\x80\xa6,tn]<:T\xe2\x80\xb2[t1,\xe2\x80\xa6,tn]
这确实很难理解(恕我直言),但我相信这意味着为了Variantish在 中保持协变T,你必须能够写
Variantish[Dog, TVar] <: Variantish[Animal, TVar]\nRun Code Online (Sandbox Code Playgroud)\n\n对于任何 TVar有意义的事情Variantish[Animal, TVar]。但这对于其中一些TVar,例如Inv[Animal]. 这就是为什么它在那个地方是被禁止的。