类型方差的另一个(更简单的)问题



我昨天在这里发布了这个问题的(looong(版本: 类型差异问题

长话短说,这个:

class A[-P, T <: P]

不编译(它抱怨,"P 出现在类型 <中的协变位置:T>

我认为这还不够。按照这种逻辑,这样的东西也应该是非法的:class B[+T <: String]-B[String]应该是B[Any]的子类,但后者是无效的。

而且,这个:

class C[T, -P >: T] 

实际上确实可以编译。这和上面A不是一模一样吗?

这些是微妙的不同。

class Test[-P, T <: P]

说"让P是一个逆变和无限变化的类型参数,A[Foo, Bar]0是P的一个子类型。也就是说,在检查类型是否对P有效时,完全忽略T。只有这样,T才被约束为P的子类型。这是非法的,原因你已经知道了。你可以从Test[Any, String]开始,因为P是无限逆变的,所以它可以变得Test[Nothing, String],突然间你就有了String <: Nothing

class tseT[T, -P :> T] // Code highlighters HATE him. Click to find out why.

说"让A[Nothing, Bar]0是一个不变化且无界的类型参数,然后P是一个受T下界的逆变类型参数。这是一点点不同,因为这次P的方差受到下界T的约束。P仍然逆变,但不能低于T,否则会违反P >: T。这是安全的,因为你可以从tseT[String, Any]开始,然后P只要它仍然是Bar0的超类型,就只能向下变化,所以P向下变化到Nothing是非法的。

请注意,类型参数是从左到右处理的。这就是为什么第一个示例被声明为无效,而不是推断绑定P >: T,因为在处理P时尚未声明T,并且这样的绑定无论如何都是前向引用。

最新更新