ada*_*amw 10 scala scala-compiler
请考虑以下代码段:
trait X[-T]
object Y extends X[Nothing]
def a[T](x: X[T]): X[T] = x
a(Y)
Run Code Online (Sandbox Code Playgroud)
上述(2.12.3)的汇编失败了:
type mismatch;
found : Y.type
required: X[T]
a(Y)
^
Run Code Online (Sandbox Code Playgroud)
如果符合以下情况,这将编
Nothing(例如object Y extends X[String])a不在T其返回类型中使用(例如def a[T](x: X[T]): Unit = {})a明确给出了类型参数(即a[Nothing](Y))T 是协变的,而不是逆变的(如果它是不变的也会失败)这是编译器中的一些特例Nothing吗?
作为一个"有趣"的解决方案,以下似乎工作正常:
trait X[-T]
object Y extends X[Nothing]
def a[T, U <: T](x: X[T]): X[U] = x
a(Y)
Run Code Online (Sandbox Code Playgroud)
我将尝试逐行解释代码
第 1 行:trait X[-T]-> 特征 X 在类型 T 中是逆变的。因此,您可以将类型 X[T] 的任何变量替换为其子类型。在逆变类型的情况下,如果 B 是 A 的子类型,则 Z[A] 是 Z[B] 的子类型。
第 2 行:object Y extends X[Nothing]-> 对象 Y 的类型为 X[Nothing]。请注意,Nothing 是所有其他类型的子类型。
第 3 行:def a[T](x: X[T]): X[T] = x-> 定义一个采用 X[T] 类型参数的表达式。因为特征 X 在类型 T 中是逆变的,所以您还可以传递 X[T] 的子类型,即 X[N],使得 T 是 N 的子类型
第 4 行:a(Y)-> 使用 X[Nothing] 类型的参数调用表达式“a”。由于编译器不知道“a”的参数类型,因此无法确定 X[Nothing] 是否是 X[T] 的子类型。有多种方法可以解决这个问题
Solution 1: `a[Nothing]` -> explicitly defining the type
Solution 2: `tait X[+T]` -> make X covariant in type T. In this case Z[A] is subtype of Z[B] if A is subtype of B. This will work because Nothing is subtype of any other type
Run Code Online (Sandbox Code Playgroud)