警告匹配可能并非详尽无遗

muk*_*210 10 scala pattern-matching

我正在尝试下面的代码:

  val set1 = Set(1,2,3,4,5,67,8)
  val TRUE_BOOLEAN = true
  val FALSE_BOOLEAN = false
  set1.contains(4) match {
    case TRUE_BOOLEAN => println("Element found")
    case FALSE_BOOLEAN => println("Element not found")
  }
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试运行它时IntelliJ,它会在Messages标签中给出以下警告:

Warning:(11, 16) match may not be exhaustive.
It would fail on the following inputs: false, true
  set1.contains(4) match {
Run Code Online (Sandbox Code Playgroud)

然而,如果我使用truefalse不是TRUE_BOOLEANFALSE_BOOLEAN,我没有收到任何警告.

set1.contains(4) match {
    case true => println("Element found")
    case false => println("Element not found")
  }
Run Code Online (Sandbox Code Playgroud)

有人可以解释这个警告的原因,为什么它会消失truefalse.

And*_*kin 11

它产生警告,因为它不能保证匹配是详尽的.

实际上,当嵌入在正确的上下文中时,您的代码会在运行时抛出匹配错误:

class Foo {
  val set1 = Set(1,2,3,4,5,67,8)
  val TRUE_BOOLEAN = true
  val FALSE_BOOLEAN = false
  set1.contains(4) match {
    case TRUE_BOOLEAN => println("Element found")
    case FALSE_BOOLEAN => println("Element not found")
  }
}

class Bar extends Foo {
  override val TRUE_BOOLEAN = false
}

new Bar // scala.MatchError: true (of class java.lang.Boolean)
Run Code Online (Sandbox Code Playgroud)

所以警告是正确的,而不仅仅是过于保守的估计.由于每个Scala脚本都隐式嵌入到某些类"类"包装器中,因此它也可以在Scala脚本中以完全相同的方式工作,即使您不将它包装在Foo-class中也是如此.

如果将两个变量都设置为final,则常量传播正常工作,并且不会发出警告:

class Foo {
  val set1 = Set(1,2,3,4,5,67,8)
  final val TRUE_BOOLEAN = true
  final val FALSE_BOOLEAN = false
  set1.contains(4) match {
    case TRUE_BOOLEAN => println("Element found")
    case FALSE_BOOLEAN => println("Element not found")
  }
}
Run Code Online (Sandbox Code Playgroud)

编译得很好,没有警告.