Vector的模式匹配"case Nil"

Kev*_*ith 18 scala

在阅读了关于如何使用模式匹配(或任何实现的集合)的帖子之后,我在这个集合上测试了模式匹配.VectorSeq

scala> x // Vector
res38: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3)

scala> x match {
     |    case y +: ys => println("y: " + "ys: " + ys)
     |    case Nil => println("empty vector")
     | }
<console>:12: error: pattern type is incompatible with expected type;
 found   : scala.collection.immutable.Nil.type
 required: scala.collection.immutable.Vector[Int]
Note: if you intended to match against the class, try `case _: <none>`
                 case Nil => println("empty vector")
                      ^
Run Code Online (Sandbox Code Playgroud)

这里的dhg答案解释+:如下:

object +: {
  def unapply[T](s: Seq[T]) =
    s.headOption.map(head => (head, s.tail))
}
Run Code Online (Sandbox Code Playgroud)

REPL 告诉我那个

scala> Vector[Int]() == Nil
res37: Boolean = true
Run Code Online (Sandbox Code Playgroud)

...为什么我不能用这个case Nil陈述Vector

0__*_*0__ 29

比较Vector[Int]() == Nil是可能的,因为您比较的类型级别没有约束; equals另一方面,无论集合类型如何,都允许集合的实现执行逐元素比较:

Vector(1, 2, 3) == List(1, 2, 3)  // true!
Run Code Online (Sandbox Code Playgroud)

在模式匹配中,Nil当类型与list(它是a Vector)无关时,你不能有空列表()的情况.

但是你可以这样做:

val x = Vector(1, 2, 3)

x match {
  case y +: ys => println("head: " + y + "; tail: " + ys)
  case IndexedSeq() => println("empty vector")
}
Run Code Online (Sandbox Code Playgroud)

但我建议在这里使用默认情况,因为如果x没有head元素,它必须在技术上是空的:

x match {
  case y +: ys => println("head: " + y + "; tail: " + ys)
  case _ => println("empty vector")
}
Run Code Online (Sandbox Code Playgroud)

  • 抓住所有人可能会意外地抓住比你想象的更多的案件.对于清楚枚举(密封)类型,我建议不要使用`_`.例如,使用`List`你有编译器检查:`def foo(xs:List [Any])= xs match {case head :: tail =>"yes"}`给你警告,`def foo(xs: Vector [Any])= xs match {case head +:tail =>"yes"}`没有.对于`List`,我会使用`case Nil`,索引seq`c​​ase _` ... (2认同)