【问题标题】:Scala lower type bounds and covarianceScala 下界和协方差
【发布时间】:2012-05-12 04:31:06
【问题描述】:

我正在阅读此页面http://www.scala-lang.org/node/137,我了解协方差和下限是什么,但不清楚的是这一行:

不幸的是,这个程序没有编译,因为协方差 仅当类型变量仅用于 协变位置。由于类型变量 T 作为参数类型出现 方法前置,这条规则被打破了。

为什么elem 必须是T 的超类型的一个实例,如果ListNode 已经是协变的,为什么elem 不能被添加到当前列表中。

【问题讨论】:

  • 解释很简单。类型变量 T 显示为参数类型。这不是协变位置。这里到底有什么问题?

标签: scala covariance lower-bound


【解决方案1】:
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]):

val foo : Foo[Super] = new Foo[Sub] {
  override def bar(x: Sub) = x.subMethod
}

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

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

【讨论】:

  • 好的,我明白了,现在从 scala 站点的“这个程序不编译”这一行来看,这并不意味着我们实际上违反了这个特定代码中的某些内容,并且我们没有继承 Foo [SomeClass] 明确地,编译器只是在防止潜在的运行时错误,我错了吗?
  • 你是对的,但这就像编译器应用任何其他静态类型规则一样,比如不允许你在字符串上调用 List 方法。如上所示,允许方法的争论是协变类型在逻辑上是不一致的,所以它不允许。
猜你喜欢
  • 2018-02-02
  • 2016-08-24
  • 1970-01-01
  • 2012-06-29
  • 1970-01-01
  • 2021-01-24
  • 2013-05-31
  • 2016-10-16
  • 1970-01-01
相关资源
最近更新 更多