再次模式匹配列表时,可以使用Nil检查空列表.但是,如果基础类型是Iterable,您仍然可以检查Nil,它将为空集等中断...请参阅以下REPL会话:
scala> val l: Iterable[Int] = List()
l: Iterable[Int] = List()
scala> l match {
| case Nil => 1
| case _ => 2
| }
res0: Int = 1
scala> val l: Iterable[Int] = Set()
l: Iterable[Int] = Set()
scala> l match {
| case Nil => 1
| case _ => 2
| }
res2: Int = 2
Run Code Online (Sandbox Code Playgroud)
问题是 - 我该如何防止这类问题?显然,如果l是类型List,那就不是bug.如果l的类型为Set,则不会编译.但是,如果我们有一个具有列表的类,定义一个模式以这种方式匹配的函数,然后有人改变该类以采用通用迭代呢?这种Nil vs. _模式总体上是一个坏主意吗?
kir*_*uku 12
一种可能性是使用警卫:
scala> val xs: Iterable[Int] = Set()
xs: Iterable[Int] = Set()
scala> xs match { case xs if xs.isEmpty => 1 case _ => 2 }
res0: Int = 1
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用if-else-expression(如果你只有一个或两个条件要检查,效果最好):
scala> if (xs.isEmpty) 1 else 2
res1: Int = 1
Run Code Online (Sandbox Code Playgroud)
将scrutinee转换为列表以消除疑虑.
l.toList match {
case Nil => 1
case xs => 2
}
Run Code Online (Sandbox Code Playgroud)