为什么scala编译器有时会对“模式匹配”发出警告,有时候不会?

时间:2014-07-01 04:24:35

标签: scala pattern-matching

首先定义一个列表:

val list = List(1,2,3)

Scala编译器发出警告(即使它可以匹配):

list match {
  case head :: tail => println(s"h:${head} ~ t: ${tail}")
}

Scala编译器不会发出警告(即使它不匹配):

list match {
  case List(a,b) => println("!!!")
}

我无法理解第二个

1 个答案:

答案 0 :(得分:11)

"匹配可能并非详尽无遗"仅在类型为sealed类的模式匹配时给出警告,并且只有子类或子对象的子集。 List是一个带有子类::和子对象Nil的密封类,类似于:

sealed abstract class List[+T]
class ::[+T] extends List[+T]
object Nil extends List[Nothing]

如果你有一个match并且没有::的案例和一个Nil的案例,也没有一个案例可能与任何案件相匹配List,Scala知道这场比赛并不详尽,并且会报告。 case _会匹配任何内容,并会阻止警告。但是List(a, b)也会阻止警告,因为Scala不知道它是否只匹配某些子类。

当您使用List作为提取程序时,就像在List(a, b)中一样,您使用提取程序List.unapplySeq来拆分匹配的值。 Scala并没有尝试对提取器的行为进行假设,因此也不知道匹配并非详尽无遗。在不知道List.unapplySeq的实现细节的情况下,没有办法知道它不能很好地匹配所有内容并返回所需的两个值。