Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala下界与协方差_Scala_Covariance_Lower Bound - Fatal编程技术网

Scala下界与协方差

Scala下界与协方差,scala,covariance,lower-bound,Scala,Covariance,Lower Bound,我正在阅读这一页,我了解协方差是什么,以及下限,但不清楚的是这一行: 不幸的是,这个程序没有编译,因为协方差 仅当类型变量仅在中使用时,才可以进行注释 协变位置。因为类型变量T显示为参数类型 对于方法prepend,此规则已被破坏 为什么elem必须是T的超类型的实例,如果ListNode已经是协变的,为什么elem不能在当前列表的前面 class Super {override def toString = "Super"} class Sub extends Supe

我正在阅读这一页,我了解协方差是什么,以及下限,但不清楚的是这一行:

不幸的是,这个程序没有编译,因为协方差 仅当类型变量仅在中使用时,才可以进行注释 协变位置。因为类型变量T显示为参数类型 对于方法prepend,此规则已被破坏

为什么
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
上是协变的,所以这是有效的(一个简单的上溯,因为
Foo[Sub]
Foo[Super]
):

现在,据我们所知,
foo
是一个
foo[Super]
和任何其他方法一样,但是它的
bar
方法不起作用,因为
bar
实现需要一个子
Sub

foo.bar(sup) // would cause error!

解释很简单。类型变量T显示为参数类型。这不是协变位置。这里到底是什么引起了问题?好吧,我明白了,从scala站点的“此程序不编译”这一行来看,这并不意味着我们实际上违反了这段特定代码中的某些内容,我们没有显式地对Foo[SomeClass]进行子类化,编译器只是为了防止潜在的运行时错误,我错了吗?你是对的,但这就像编译器应用任何其他静态类型规则一样,比如不允许对字符串调用List方法。如上所示,允许方法的参数为协变类型在逻辑上是不一致的,因此它不允许您这样做。
foo.bar(sup) // would cause error!