Scala 中的模式匹配类似于 Java 中的 switch 语法,但是更加强大。
基本语法
模式匹配语法中,采用 match 关键字声明,每个分支采用 case 关键字进行声明,当需要匹配时,会从第一个 case 分支开始,如果匹配成功,那么执行对应的逻辑代码,如果匹配不成功,继续执行下一个分支进行判断。如果所有 case 都不匹配,那么会执行 case _ 分支,类似于 Java 中 default 语句。
object MatchDemo01 {
def main(args: Array[String]): Unit = {
val oper = 1
val n1 = 20
val n2 = 10
var res = 0
oper match{
case '+' => res = n1 + n2
case '-' => res = n1 - n2
case '*' => {
res = n1 * n2
println("计算完成!")
}
case '/' => res = n1/n2
case 1 =>println("匹配到1")
case 1.1 =>println("匹配到1.1")
case _ => println("oper error")
}
println("res="+res)
}
}
match 的细节和注意事项
- 如果所有 case 都不匹配,那么会执行 case _ 分支,类似于 Java 中 default 语句, case _ 分支要写在最后一行
- 如果所有 case 都不匹配,又没有写 case _ 分支,那么会抛出MatchError
- 每个 case 中,不用 break 语句,自动中断 case
- 可以在 match 中使用其它类型,而不仅仅是字符
- => 等价于 java swtich 的 :
- => 后面的代码块到下一个 case, 是作为一个整体执行,可以使用{} 扩起来,也可以不扩
守卫
如果想要表达匹配某个范围的数据,就需要在模式匹配中增加条件守卫。
object MatchIfDemo01 {
def main(args: Array[String]): Unit = {
var num = 5
num match {
case _ if num>0 && num<10 =>println(num+"是一个小于10且大于0的数")
case _ if num>0 => println(num + "大于0")
case _ if num<0 => println(num + "小于0")
case _ =>println(num + "是0")
}
}
}
模式中的变量
如果在 case 关键字后跟变量名,那么 match 前表达式的值会赋给那个变量
object MatchIfDemo01 {
def main(args: Array[String]): Unit = {
val num =10
num match {
case matchNum =>println(num+"的2倍是"+ matchNum*2)
case _ =>println("ok")
}
}
}
类型匹配
可以匹配 对象的任意类型,这样做避免了使用 isInstanceOf 和 asInstanceOf 方法。有点遗憾的是,通过测试看出不能匹配出集合中元素的类型,比如List[Int],List[String],match时二者无法区分。
object MatchIfDemo01 {
def main(args: Array[String]): Unit = {
for (a <- 1 to 5) {
var obj = if (a == 1) 1
else if (a == 2) '2'
// else if (a == 3) Map(33 -> "33")
// else if (a == 4) Map("44" -> 44)
else if (a == 3) List(33)
else if (a == 4) List("44")
else Map(55 -> 55)
obj match {
case a: Int => println(a + "是整数")
case b: Char => println(b + "是字符")
// case c: Map[Int, String] => println(c +"Map[Int, String]")
// case d: Map[String, Int] => println(d +"Map[String, Int]")
case c: List[Int] => println(c +"List[Int]")
case d: List[String] => println(d +"List[String]")
case _ => println("未匹配上")
}
}
}
}
对象匹配
对象匹配,什么才算是匹配呢?规则如下:
- case 中对象的 unapply 方法(对象提取器)返回 Some 集合则为匹配成功
- 返回 None 集合则为匹配失败
object MatchObject {
def main(args: Array[String]): Unit = {
//模式匹配使用
// case A(n)的运行机制
// 1.当匹配到case A(n),调用A的unapply(z:Double),z的值就是num
//2.如果对象提取器unapply(z:Double)返回的是Some(4),则表示匹配成功
//同时,将4的值赋给A(n)的n
//如果对象提取器返回的是None,则表示匹配不成功
val num:Double = A(4.0)
println(num)
num match{
case A(n) => println("匹配成功 n="+n)
case _ => println("nothing matched")
}
}
}
object A{
def unapply(z: Double): Option[Double] = {
println("unapply被调用z是="+z)
// Some(math.sqrt(z))
None
}
def apply(z:Double):Double = z*z
}
补充Option对象的用法:Option对象返回值为两种类型:Some集合 和 None
object OptionDemo01 {
def divided(a:Int,b:Int):Option[Int]={
if(b!=0) Some(a/b) else None
}
def main(args: Array[String]): Unit = {
println(divided(15,0).getOrElse(3)) //
}
}
当返回值为None时,可通过getOrElse方法来获得默认值