当我看到标志-Xlint:unsound-match时,我正在研究使非穷举匹配成为Scala中的编译错误的方法。但是,我找不到太多的信息,发现的一个示例在带有和不带有标志的情况下均相同,因此我真的不知道何时会有所帮助。有人可以解释它和/或提供一个在没有该标志的情况下进行编译但不发出警告的匹配示例,但会生成警告的示例吗?

最佳答案

下面的程序可以正常编译,但是在运行时因ClassCastException崩溃:

case class A()
object B extends A() {
  def bar() = println("only B has this method")
}

A() match {
  case x @ B => x.bar()
  case _ => ()
}

发生这种情况是因为==用于检查x是否为B,但是在这种情况下,==的行为非常奇怪:
case class A()
object B extends A()
B == A() // returns true, because extending from case classes is evil.

这似乎是因为B继承了case类的equals,所以

所有B == a
  • a: A,但同时
  • a: B.type对于几乎所有的a: A(除B本身以外的所有其他字符)均为false。

  • 在较旧的scalac版本(例如2.15)上使用-Xlint:unsound-match进行编译时,该代码会产生以下警告:
     warning: The value matched by $anon.this.B is bound to x, which may be used under the
    unsound assumption that it has type this.B.type, whereas we can only safely
    count on it having type this.A, as the pattern is matched using `==` (see scala/bug#1503).
      case x @ B => x.bar()
               ^
    one warning found
    

    而如果没有-Xlint,则什么也不会发生。

    请注意,-Xlint:unsound-match似乎已在较新版本的编译器中删除(至少在最近的提交中找不到),因此,显然,它现在什么也不做。

    10-08 06:39