Seq的匹配

- 3 mins

Seq的匹配请见以下代码:

val nonEmptySeq    = Seq(1, 2, 3, 4, 5)                              // <1>
val emptySeq       = Seq.empty[Int]
val nonEmptyList   = List(1, 2, 3, 4, 5)                             // <2>
val emptyList      = Nil
val nonEmptyVector = Vector(1, 2, 3, 4, 5)                           // <3>
val emptyVector    = Vector.empty[Int]
val nonEmptyMap    = Map("one" -> 1, "two" -> 2, "three" -> 3)       // <4>
val emptyMap       = Map.empty[String,Int]

def seqToString[T](seq: Seq[T]): String = seq match {                // <5>
  case head +: tail => s"$head +: " + seqToString(tail)              // <6>
  case Nil => "Nil"                                                  // <7>
}

for (seq <- Seq(                                                     // <8>
    nonEmptySeq, emptySeq, nonEmptyList, emptyList, 
    nonEmptyVector, emptyVector, nonEmptyMap.toSeq, emptyMap.toSeq)) {
  println(seqToString(seq))
}

由于Seq的定义就是由一个head和一个tail构成,因此,对Seq的匹配分为两种情况,:

以上<5>和<6>就示例了如何匹配Seq(List || Vector)的方法。

这里很明显的暗示了一点:所有的Seq,要么是空(Nil),要么非空。

这里需要注意一下:seqToString函数中match的head和tail是任意的两个变量名,而不是Seq的方法名(Seq有名为head和tail的方法名),是用于提取Seq的head和tail元素的。

以下是执行结果:

1 +: 2 +: 3 +: 4 +: 5 +: Nil
Nil
1 +: 2 +: 3 +: 4 +: 5 +: Nil
Nil
1 +: 2 +: 3 +: 4 +: 5 +: Nil
Nil
(one,1) +: (two,2) +: (three,3) +: Nil
Nil

在Scala 2.10之前,处理List还有另一种很相似的方法:

val nonEmptyList = List(1, 2, 3, 4, 5)
val emptyList    = Nil

def listToString[T](list: List[T]): String = list match {
  case head :: tail => s"($head :: ${listToString(tail)})"           // <1>
  case Nil => "(Nil)"
}

for (l <- List(nonEmptyList, emptyList)) { println(listToString(l)) }

输出也很类似:

(1 :: (2 :: (3 :: (4 :: (5 :: (Nil))))))
(Nil)
comments powered by Disqus
rss facebook twitter github youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora