1. match
Scala中的match表达式可以让你用任意的模式来选择,缺省的样例以下划线(_) 来表示。样例可以是任何常量、字符串等,每个可选项的最后不需要加上break(Scala中break是隐含的,不会出现某个可选项执行完继续执行下一个可选项的情况)。match表达式可以返回值。
2. 模式匹配
模式匹配应用场合:switch语句、类型查询、以及析构(获取复杂表达式中的不同部分)。
2.1 守卫
守卫可以是任何Boolean条件。
val ch = ""
val sign = ch match {
case "+" => 1
case "-" => -1
case _ if ch.isEmpty() => 0
case _ => -999
}
println(sign) // 0
2.2 模式匹配常量、类型、数组/列表/元组
// 匹配常量:如果常量是小写字母开头,加反引号
val a = 123
val b = 123
val res01 = a match {
case Pi => "a is Pi"
case `b` => b
case _ => "unknown"
}
println(res01) // 123
// 匹配类型
val obj: Any = "1232dfsd"
val res02 = obj match {
case x: Int => "Int: " + x
case x: String if (obj.toString.toCharArray.filter(x => Character.isDigit(x)).size == obj.toString.size) => "String: " + Integer.parseInt(x)
case x: BigInt => "BigInt: " + Integer.MAX_VALUE
case _ => 0
}
println(res02) // 0
// 匹配数组、列表和元组
def f(arr: Array[Any]): String = arr match {
case Array(0) => "0"
case Array(x, y) => x + " " + y
case Array(0, _*) => "0 ..."
case _ => "something else"
}
println(f(Array(0, "aa"))) // 0 aa
println(f(Array(0))) // 0
println(f(Array("aa"))) // something else
println(f(Array(0, 3, 5))) // 0 ...
2.3 提取器
见 6. Scala中的apply、update、unapply、unapplySeq
3. 样例类
Scala提供样例类对模式匹配进行了优化。当声明样例类的时候,以下自动发生:
- 构造器中的每一个参数都成为val,除非被显示地声明为var
- 在伴生对象中提供apply方法让你不用new关键字就能构造出相应的对象
- 提供unapply方法让模式匹配可以工作
- 将生成 toString、equals、hashCode方法
package basic
object CaseClass {
def main(args: Array[String]): Unit = {
// 样例类自动包含了apply方法
val stu = Student("zs", 34)
println(s"${stu.name} ${stu.age}") // 样例类的变量默认为可外部访问的,但是不能修改(默认为val,除非修改成var)
// 样例类默认提供 unapply 方法
val Student(name, age) = stu
println(s"$name $age")
// 密封类模仿枚举值()
val color: TrafficColor = Red
color match {
case Green => println("可以通过")
case Yellow => println("请快速通过")
case Red => println("请止步")
case _ => println("unknown")
}
}
}
case class Student(name: String, age: Int)
sealed abstract class TrafficColor // 密封类的所有子类必须和密封类在同一个文件中
case object Green extends TrafficColor
case object Red extends TrafficColor
case object Yellow extends TrafficColor