Scala模式匹配

模式匹配

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)
    }
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

catch that elf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值