Scala:不正确的警告"匹配可能不详尽"

Jus*_*s12 2 scala

请考虑以下代码段:

sealed abstract class Bar
object B1 extends Bar
object B2 extends Bar
object B3 extends Bar
case class A(bar:Bar)

def foo(a:A) = a match {
    case A(bar@(B1|B2)) =>
        bar match { // gives warning here
            case B1 => 
            case B2 => 
        } 
    case _ =>
}
Run Code Online (Sandbox Code Playgroud)

在上面,我确保第一种情况只在A类型A(B1)A(B2)(至少我认为这意味着)时匹配.但是,我收到以下错误:

warning: match may not be exhaustive.
It would fail on the following input: B3
       bar match {
       ^
Run Code Online (Sandbox Code Playgroud)

任何人都可以详细说明警告的来临吗?

编辑:答案后,似乎编译器类型barBar无需记住它匹配.这绝对不是一个bug.该编译器足够智能,不会发出以下警告:

sealed abstract class Bar
object B1 extends Bar
object B2 extends Bar
object B3 extends Bar
case class A(bar:Bar)

def foo(a:A) = a match {
    case A(B1|B2) =>
        a match { // no warning
            case A(B1) => 
            case A(B2) => 
        } 
    case _ =>
}
Run Code Online (Sandbox Code Playgroud)

End*_*Neu 5

我想这是因为给出的类型bar是超类型(bar可能是一个B1B2唯一的常见类型Bar),所以理论上它仍然可以是一个B3而编译器对此不够智能:

def foo(a:A) = a match {
  case A(bar@(B1|B2)) =>
    bar match { // bar here has a Bar type
        case B1 => 
        case B2 => 
    } 
  case _ =>
}
Run Code Online (Sandbox Code Playgroud)

无论如何,当你有一个具有相同结果的平面匹配时,有一个嵌套匹配的重点是什么?

  • @ Jus12我只是把它称为限制,而不是一个适当的错误.在这种情况下,编译器无法单独从"bar"类型看到匹配是穷举的,即从"A",它需要有关其实际值的信息.它与`if(x == 0){x match {case 0 => ...}}`没有什么不同,这是详尽的,但需要一个非常聪明的编译器来发现它. (2认同)