简单模式匹配

Scala中没有提供与Java语言中switch类似的语法,但是提供了一个更加强大的模式匹配功能。模式匹配是一个Scala 概念,它看上去与其它语言中的一个switch 语句很类似。不过,它是一个比switch 语句更强大的工具。根据值检查模式的过程称为模式匹配。

一个模式匹配的简单应用是作为多级if-else 语句的替代,这可以提高代码的可读性。模式匹配不使用关键字switch,Scala使用关键字match。每个可能的匹配由关键字case 处理。如果有一个case 被匹配到,那么右箭头右侧的代码被执行。其中下划线_代表默认case。如果前面没有一个case 匹配上的话,默认case 的代码会被执行。与switch 语句不同,在每个case 后的代码不需要break 语句。只有匹配的case 会被执行。另外,每个=>右侧的代码是一个表达式,返回一个值。因此,一个模式匹配语句本身是一个表达式,返回一个值。

请看下面的示例:根据输入的数字,给出对应的星期。

val day = 8
val month = day match{
    case 1 => "星期一"
    case 2 => "星期二"
    case 3 => "星期三"
    case 4 => "星期四"
    case 5 => "星期五"
    case 6 => "星期六"
    case 7 => "星期天"
    case _ => "不正确"
}
println(month)

输出结果为:

不正确

【示例】从控制台输入一个整数,给出对应的月份描述。

import java.io._

print("控制台输入一个整数 :")
val br = new BufferedReader(new InputStreamReader(System.in));
val line = br.readLine().toInt
val month = line match {
      case 1  => "一月份"
      case 2  => "二月份"
      case 3  => "三月份"
      case 4  => "四月份"
      case 5  => "五月份"
      case 6  => "六月份"
      case 7  => "七月份"
      case 8  => "八月份"
      case 9  => "九月份"
      case 10 => "十月份"
      case 11 => "十一月份"
      case 12 => "十二月份"
      case _  => "无效的月份值"  // 默认值
}

println("month:" + month)
br.close()

说明:在Scala 2.11中,可以用scala.io.StdIn.readLine()函数从控制台读取一行输入。如果要读取数字、Boolean或者是字符,可以用readInt、readDouble、readByte、readShort、readLong、readFloat、readBoolean或者readChar。

import scala.io.StdIn.readLine

val input = readLine("请输入内容:")
println("您输入的是:" + input)
printf("您输入的是:%s\n", input)
println(s"您输入的是:$input")

【例】使用模式匹配实现一个简单的菜单选择。

import scala.io.StdIn

object demo {
  def main(args: Array[String]): Unit = {
    // 类似switch
    val taste =
      """
        |1 - "香橙味"
        |2 - "葡萄味"
        |3 - "水蜜桃味"
        |4 - "菠萝味"
      """.stripMargin
    println(s"口味:$taste")

    val input = StdIn.readLine("请选择您的口味:")

    // 模式匹配
    val msg = input match {
      case "1" => "香橙味"
      case "2" => "葡萄味"
      case "3" => "水蜜桃味"
      case "4" => "菠萝味"
      case _ => "不存在的口味"
    }

    println(s"您选择的是$msg")
  }
}

一个case语句也可以匹配多个条件。请看下面的代码:

val day = 6
val weekDay = day match{
    case 1|2|3|4|5 => "工作日"
    case 6|7 => "周末"
    case _ => "不正确"
}

匹配更多的类型:

    println("---------------------------")
    // 一个case语句匹配多个条件
    // 匹配多个值
    val i = 5
    i match {
      case 1 | 3 | 5 | 7 | 9  => println("奇数")
      case 2 | 4 | 6 | 8 | 10 => println("偶数")
    }

    // 匹配字符串类型
    val cmd = "stop"
    cmd match {
      case "start" | "go"           => println("starting")
      case "stop" | "quit" | "exit"    => println("stopping")
      case _                    => println("doing nothing")
    }

《Spark原理深入与编程实战》