六、Scala中的模式匹配

Scala中的模式匹配类似于Java中的switch语法:

int i = 10
switch (i) {
 case 10 :
System.out.println("10");
break;
 case 20 : 
System.out.println("20");
break;
 default : 
System.out.println("other number");
break;
}

但是Scala从语法中补充了更多的功能,所以更加强大。

1.基本语法

模式匹配语法中,采用match关键字声明,每个分支采用case关键字进行声明,当需要匹配时,会从第一个case分支开始,如果匹配成功,那么执行对应的逻辑代码,如果匹配不成功,继续执行下一个分支进行判断。如果所有case都不匹配,那么执行case_ 分支,类似于Java中的default语句。

object TestMatchCase {
 def main(args: Array[String]): Unit = {
 var a: Int = 10
 var b: Int = 20
 var operator: Char = 'd'
 var result = operator match {
 case '+' => a + b
 case '-' => a - b
 case '*' => a * b
 case '/' => a / b
 case _ => "illegal"
 }
 println(result)
 }

1)说明
(1)如果所有 case 都不匹配,那么会执行 case _ 分支,类似于 Java 中 default 语句,
若此时没有 case _ 分支,那么会抛出 MatchError。
(2)每个 case 中,不需要使用 break 语句,自动中断 case。
(3)match case 语句可以匹配任何类型,而不只是字面量。
(4)=> 后面的代码块,直到下一个 case 语句之前的代码是作为一个整体执行,可以
使用{}括起来,也可以不括。

2. 模式守卫

1)说明
如果想要表达匹配某个范围的数据,就需要在模式匹配中增加条件守卫。
2)案例实操

object TestMatchGuard {
 def main(args: Array[String]): Unit = {
 def abs(x: Int) = x match {
 case i: Int if i >= 0 => i
 case j: Int if j < 0 => -j
 case _ => "type illegal"
 }
 println(abs(-5))
 }
}

3.模式匹配类型

3.1 匹配常量

1)说明
Scala 中,模式匹配可以匹配所有的字面量,包括字符串,字符,数字,布尔值等等。

object TestMatchVal {
 def main(args: Array[String]): Unit = {
 println(describe(6))
 }
 def describe(x: Any) = x match {
 case 5 => "Int five"
 case "hello" => "String hello"
 case true => "Boolean true"
 case '+' => "Char +"
 }
}

3.2 匹配类型

需要进行类型判断时,可以使用前文所学的 isInstanceOf[T]和 asInstanceOf[T],也可使
用模式匹配实现同样的功能。

object TestMatchClass {
 def describe(x: Any) = x match {
 case i: Int => "Int"
 case s: String => "String hello"
 case m: List[_] => "List"
 case c: Array[Int] => "Array[Int]"
 case someThing => "something else " + someThing
 }
 def main(args: Array[String]): Unit = {
 //泛型擦除
 println(describe(List(1, 2, 3, 4, 5)))
 //数组例外,可保留泛型
 println(describe(Array(1, 2, 3, 4, 5, 6)))
 println(describe(Array("abc")))
 }
}

3.3 匹配数组

1)说明
scala 模式匹配可以对集合进行精确的匹配,例如匹配只有两个元素的、且第一个元素
为 0 的数组。
2)案例实操

object TestMatchArray {
 def main(args: Array[String]): Unit = {
 for (arr <- Array(Array(0), Array(1, 0), Array(0, 1, 0), 
Array(1, 1, 0), Array(1, 1, 0, 1), Array("hello", 90))) { // 对
一个数组集合进行遍历
 val result = arr match {
 case Array(0) => "0" //匹配 Array(0) 这个数组
 case Array(x, y) => x + "," + y //匹配有两个元素的数
组,然后将将元素值赋给对应的 x,y
 case Array(0, _*) => "以 0 开头的数组" //匹配以 0 开头和
数组
 case _ => "something else"
 }
 println("result = " + result)
 }
 }
}

3.4 匹配对象及样例类

object User{
 def apply(name: String, age: Int): User = new User(name, age)
 def unapply(user: User): Option[(String, Int)] = {
 if (user == null)
 None
 else
 Some(user.name, user.age)
 }
}
object TestMatchUnapply {
 def main(args: Array[String]): Unit = {
 val user: User = User("zhangsan", 11)
 val result = user match {
 case User("zhangsan", 11) => "yes"
 case _ => "no"
 }
 println(result)
 }
}

➢ val user = User(“zhangsan”,11),该语句在执行时,实际调用的是 User 伴生对象中的
apply 方法,因此不用 new 关键字就能构造出相应的对象。
➢ 当将 User(“zhangsan”, 11)写在 case 后时[case User(“zhangsan”, 11) => “yes”],会默
认调用 unapply 方法(对象提取器),user 作为 unapply 方法的参数,unapply 方法
将 user 对象的 name 和 age 属性提取出来,与 User(“zhangsan”, 11)中的属性值进行
匹配
➢ case 中对象的 unapply 方法(提取器)返回 Some,且所有属性均一致,才算匹配成功,
属性不一致,或返回 None,则匹配失败。
➢ 若只提取对象的一个属性,则提取器为 unapply(obj:Obj):Option[T]
若提取对象的多个属性,则提取器为 unapply(obj:Obj):Option[(T1,T2,T3…)]
若提取对象的可变个属性,则提取器为 unapplySeq(obj:Obj):Option[Seq[T]]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值