文章目录

  • ​​模式匹配​​
  • ​​类型匹配​​
  • ​​匹配数组​​
  • ​​匹配List​​
  • ​​元组匹配​​
  • ​​对象匹配​​
  • ​​表达式中的模式匹配​​

模式匹配

Scala 中模式匹配类似于java中的switch,但是更加强大
模式匹配的语法采用 match关键字声明,每个分支采用case进行声明,
从第一个case 开始如果匹配成功那么执行对应的逻辑代码,执行完成后自动终止终止代码块执行(不需要手工填写break)。如果匹配不成功则进行下一个分支判断
,如果所有的case不匹配那么执行 case _ 分支(类似于java switch 中的 default)
注意事项
1)如果所有的都不匹配 那么 执行 case _ 分支,如果没有case _ 分支 则代码报错
2)case 最后不用加 break ,会自动中断之后的 case操作
3)match 支持其他类型 不仅是字符串
4)case 后 到下一个case 的代码 是一个代码块 可以用{} 扩起来 也可以不扩
5)如果case后面有条件守卫即if,那么 这时的 _ 不表示默认匹配,
6)如果 case 关键字后跟变量名 ,那么 match 前表达式的值会赋给该变量
示例

def test: Unit ={
val oper:Any ="/";
val n1=29
val n2=10
var res=0
oper match{
case "+" => res = n1+n2
case "-" => res= n1-n2
case 1 => res= n1-n2
//守卫
case _ if oper.equals("*") =>res=n1*n2
case myoper if myoper.equals("/") => res=n1/n2 //赋值给变量
case _ => res = -1
}
println("res="+res)
}

类型匹配

注意事项
1)Array[Int] 和 Array[String] 是两种类型 Map[String,Int] 和 Map[Int,String] 也是不同类型 以此类推
2)在进行匹配时,编译器会先检测是否有可能匹配,如果没有可能编译器会直接报错
3) case c:Array[String] 表示先把表达式赋值给变量c 然后再进行匹配 , case _:Array[Int] => “对象是一个Int数组” 表示隐藏了变量名
示例

def test: Unit ={
val a =8
//根据a的取值 obj取值为不同的类型
val obj = if(a==1)1
else if(a==8) Array("1")

val result = obj match{
case a:Int => a
case c:Array[String] => "对象是一个字符串数组:"+c
//这里的 _表示隐藏变量名
case _:Array[Int] => "对象是一个Int数组"
case _ =>"默认值"
}
println("a=["+a+"] res=["+result+"]")

}

匹配数组

1)Array(0)表示匹配只有一个元素且该元素为0 的数组
2)Array(x,y)表示匹配有两个元素的数组,并将两个元素赋值给 变量 x和y,也可以Array(x,y,z ) 以此类推
3)Array(0,_*) 匹配第一个元素是0 的数组

def test: Unit ={
val arrs2 = Array(Array(0),Array(0,1),Array(1,0,2))
var res=""
for(arr <- arrs2){
arr match{
case Array(0)=>res="单元素集合"
case Array(x,y)=>res="双元素集合x=["+x+"]y=["+y+"]"
case Array(1,_*)=>res="以1开头的数组"
}
println("arr["+arr+"]"+res)
}

}

输出结果

arr[[I@7d417077]单元素集合
arr[[I@2f7c7260]双元素集合x=[0]y=[1]
arr[[I@2d209079]以1开头的数组

匹配List

示例

def test: Unit ={
val arrs2 = Array(List(0),List(1,0),List(88),List(0,0,0))
var res=""
for(arr <- arrs2){
arr match{
case 0::Nil =>res="单元素0集合"
case x::y::Nil =>res="双元素集合x=["+x+"]y=["+y+"]"
case 0::tail =>res="以0开头的数组"
case x::Nil =>res="单元素集合元素x="+x

}
println("arr["+arr+"]"+res)
}

输出结果

arr[List(0)]单元素0集合
arr[List(1, 0)]双元素集合x=[1]y=[0]
arr[List(88)]单元素集合元素x=88
arr[List(0, 0, 0)]以0开头的数组

元组匹配

示例

def test: Unit ={
val arrs2 = Array((0,1),(1,0),(10,30),(1,1),(0,0,2))
var res=""
for(arr <- arrs2){
arr match{
case (0,_) =>res="第一个为0 的对偶元组"
case (y,0) =>res="第二个为0 的对偶元组y=["+y+"]"
case (x,y) =>res="对偶元组x=["+x+"]y=["+y+"]"
case _ =>res="默认匹配"
}
println("arr["+arr+"]"+res)
}

}

输出结果

arr[(0,1)]第一个为0 的对偶元组
arr[(1,0)]第二个为0 的对偶元组y=[1]
arr[(10,30)]对偶元组x=[10]y=[30]
arr[(1,1)]对偶元组x=[1]y=[1]
arr[(0,0,2)]默认匹配

对象匹配

怎么才算是匹配呢?规则如下:
case中对象的 unapply 方法()返回Some集合 则 为匹配成功 返回 None为匹配失败
示例

def test: Unit ={
val a = 12.0
var res= a match{

//当执行case Square(res) 时
//首先将 a 的值传递给 Square 的 unapply 方法,执行unapply 中的逻辑,
//如果返回为Some集合 则 表示匹配成功 ,并将集合中的元素 赋值给 res
// 返回的Some集合中的元素数量必须和 这里括号中的 变量数量相同 (这里只有res一个变量,返回结果也只有一个)
//当 匹配时声明多个变量时,会调用 unapplySeq 方法
//同样也是返回 Some集合(表示匹配成功),可以包含多个值,这些值按照顺序赋值给声明的变量
case Square(res) =>"匹配成功,res="+res
case _ =>"没有匹配到"
}
println(res)
}

object Square{
def unapply(arg: Double): Option[Double] = {
Some(math.sqrt(arg)) //本方法返回Some集合 就会匹配成功 返回none就会匹配失败
}
}

表达式中的模式匹配

集合便利使用模式匹配

def test: Unit ={
val map = Map("A"-> 0,"B"->2,"C"->3)
for((k,0)<-map){//只便利 值为0 的数据
println(k+"===="+0)
}
for((k,v)<-map if v==0){//只便利 值为0 的数据
println(k+"===="+v)
}
}