我正在阅读此页面http://www.scala-lang.org/node/137,我了解协方差和下限是什么,但不清楚的是这一行:
不幸的是,该程序无法编译,因为只有在类型变量仅在协变位置使用时才能使用协方差注释。由于类型变量 T 显示为方法前置的参数类型,因此该规则被打破。
为什么elem必须是 的超类型的实例T,如果ListNode已经是协变的,为什么elem不能添加到当前列表中。
我正在阅读此页面http://www.scala-lang.org/node/137,我了解协方差和下限是什么,但不清楚的是这一行:
不幸的是,该程序无法编译,因为只有在类型变量仅在协变位置使用时才能使用协方差注释。由于类型变量 T 显示为方法前置的参数类型,因此该规则被打破。
为什么elem必须是 的超类型的实例T,如果ListNode已经是协变的,为什么elem不能添加到当前列表中。
class Super {override def toString = "Super"}
class Sub extends Super {override def toString = "Sub"; def subMethod {} }
val sup = new Super
val sub = new Sub
想象一下允许以下情况:
// invalid code
class Foo[+T] {
def bar(x: T) = println(x)
}
由于Foo是 上的协变T,这是有效的(一个简单的向上转换,因为 aFoo[Sub]是 a Foo[Super]):
val foo : Foo[Super] = new Foo[Sub] {
override def bar(x: Sub) = x.subMethod
}
foo据我们所知,现在是 aFoo[Super]和其他任何方法一样,但它的bar方法不起作用,因为bar实现需要 a Sub:
foo.bar(sup) // would cause error!