9.3 匹配元组和列表
匹配字面量和枚举很简单。但是,很快我们就会意识到,消息不只有单个的字面量,还有元组或列表形式的一个序列的值。元组和列表也可以用case
表达式匹配。假定要编写一个服务,其中需要接收和处理地理坐标。如果将坐标表示成元组,就可以这样匹配:
PatternMatching/MatchTuples.scala
def processCoordinates(input: Any) {
input match {
case (a, b) => printf("Processing (%d, %d)... ", a, b)
case "done" => println("done")
case _ => null
}
}
processCoordinates((39, -104))
processCoordinates("done")
这会匹配了有两个值的任意元组,还有字面量“done”。会得到这样的输出结果:
Processing (39, -104)... done
如果传递的实参不是有两个元素的元组,或不匹配“done”,通配符就会处理它。这里printf()
语句有一个隐含的假设,元组里的值是整数。如果不是,代码就会在运行时失败——这可不好。为匹配提供类型信息,可以避免这种情况发生。我们会在9.4节“类型和卫述句的匹配”中看到。
匹配List
可以用匹配元组同样的方式。我们只要提供关心的元素即可,剩下的元素可以通过数组展开符(_*
)略去。
PatternMatching/MatchList.scala
def processItems(items: List[String]) {
items match {
case List("apple", "ibm") => println("Apples and IBMs")
case List("red", "blue", "white") => println("Stars and Stripes...")
case List("red", "blue", _*) => println("colors red, blue, ... ")
case List("apple", "orange", otherFruits @ _*) =>
println("apples, oranges, and " + otherFruits)
}
}
processItems(List("apple", "ibm"))
processItems(List("red", "blue", "green"))
processItems(List("red", "blue", "white"))
processItems(List("apple", "orange", "grapes", "dates"))
第一个和第二个case
分别期望List
里有两个和三个特定项。剩下的两个case
期待两个或更多的项,但是前两项必须是特定的。如果需要引用余下的匹配项,可以在特殊符号@
前放一个变量名(比如otherFruits
),正如上面代码所示。输出如下:
Apples and IBMs
colors red, blue, ...
Stars and Stripes...
apples, oranges, and List(grapes, dates)