繁体   English   中英

Scala 2.10.3编译器中可能存在的错误

[英]Possible bug in Scala 2.10.3 compiler

我遇到了一些看起来非常像这样的代码:

object SomeOddThing extends App {
  val c: C = new C
  val a: A = c
  val b: B = c
  // these will all print None
  println(a.x)
  println(b.x)
  println(c.x)
}

abstract class A {
  def x: Option[String] = None
}

abstract class B extends A {
  override def x: Option[String] = Some("xyz")
}

class C extends B {
  // x now has type None.type instead of Option[String]
  override def x = None
}

trait T {
  this: B =>
  override def x = Some("ttt")
}

// this won't compile with the following error
// error: overriding method x in class C of type => None.type;
//  method x in trait T of type => Some[String] has incompatible type
// class D extends C with T {}
//       ^
class D extends C with T {}

对我来说这看起来像个错误。 应该正确推断出Cx的类型,或者根本不应该编译类。

规范4.6.4仅承诺推断覆盖方法的结果类型的符合类型。

请参阅https://issues.scala-lang.org/browse/SI-7212并感谢您没有投掷。

也许它会改变:

https://groups.google.com/forum/#!topic/scala-internals/6vemF4hOA9A

更新:

协变结果类型是自然的。 它推断它通常会做的事情并不怪诞。 并且你不能再次扩大类型。 这可能是次优的,正如其他问题所说的那样。 (说到我的评论,这是一个改进,而不是一个错误本身。)

我对ML的评论:

这属于“始终注释接口方法,包括通过子类扩展的接口”。

在很多情况下,为API方法使用推断类型会将您提交给您相当避免的类型。 对于您提供给子类的接口也是如此。

对于这个问题,我们要求编译器保留最后一个明确归属的类型,这是合理的,除非它不是。 也许我们的意思是不要推断单身类型,或者什么都不是,或类似的东西。 /思维,大声

scala> trait A ; trait B extends A ; trait C extends B
defined trait A
defined trait B
defined trait C

scala> trait X { def f: A }
defined trait X

scala> trait Y extends X { def f: B }
defined trait Y

scala> trait Z extends Y { def f: C }
defined trait Z

scala> trait X { def f: A = new A {} }
defined trait X

scala> trait Y extends X { override def f: B = new B {} }
defined trait Y

scala> trait Z extends Y { override def f: C = new C {} }
defined trait Z

scala> trait ZZ extends Z { override def f: A = new C {} }
<console>:13: error: overriding method f in trait Z of type => C;
 method f has incompatible type
       trait ZZ extends Z { override def f: A = new C {} }
                                         ^

对于这个问题,None.type符合Option是什么意思?

scala> implicitly[None.type <:< Option[_]]
res0: <:<[None.type,Option[_]] = <function1>

显示None.type,None对象的单例类型,实际上是一个Option。

通常,有人说编译器避免推断单例类型,即使你想要它。

Scala中的编程说,“通常这些类型太具体而无用。”

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM