代码之家  ›  专栏  ›  技术社区  ›  mukesh210

警告匹配可能并不详尽

  •  9
  • mukesh210  · 技术社区  · 7 年前

    我正在尝试以下代码:

      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")
      }
    

    但是,当我试着运行它的时候 IntelliJ Messages 选项卡:

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

    true false 而不是 TRUE_BOOLEAN FALSE_BOOLEAN ,我没有收到任何警告。

    set1.contains(4) match {
        case true => println("Element found")
        case false => println("Element not found")
      }
    

    有人能解释一下这个警告的原因吗?为什么它会随着时间而消失 .

    1 回复  |  直到 7 年前
        1
  •  12
  •   Andrey Tyukin    7 年前

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

    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)
    

    所以警告是 而不仅仅是一个过于保守的估计。由于每个Scala脚本都隐式地嵌入到某个“类”包装器中,因此它在Scala脚本中的工作方式也完全相同,即使您没有将其包装到 Foo -班级。

    如果将两个变量都设置为 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")
      }
    }
    

    编译得很好,没有警告。