首页 > 其他 > 详细

Scala模式匹配

时间:2019-04-06 14:02:39      阅读:144      评论:0      收藏:0      [点我收藏+]

 

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

match的细节和注意事项

如果所有case都不匹配,那么执行case _ 分支,类似于Java中default语句

如果所有case都不匹配,又没有写case _ 分支,那么会抛出MatchError

每个case中,不用break语句,自动中断case

可以在match中使用其它类型,而不仅仅是字符,可以是表达式

=> 类似于 java swtich 的 :

=> 后面的代码块到下一个case, 是作为一个整体执行,可以使用{} 括起来,也可以不括。 

    for (ch <- "+-3!") {
      var sign = 0
      var digit = 0
      ch match {
        case ‘+‘ => sign = 1
        case ‘-‘ => sign = -1
        case _ if ch.toString.equals("3") => digit = 3
        case _ => sign = 2
      }
      println(ch + " " + sign + " " + digit)
    }

+ 1 0
- -1 0
3 0 3
! 2 0

守卫

如果想要表达匹配某个范围的数据,就需要在模式匹配中增加条件守卫

       case _  => digit = 3

       case _  => sign = 2 //不会走这一步,只会走一个case _

case _ => digit = 3 //默认,如果把它写在最前边,则下面的所有case就都不会走;
给模式匹配增加变量
//如果在case关键字后跟变量名,那么match前表达式的值会赋给那个变量
val ch = ‘Y‘
ch match {
case ‘+‘ => println("ok+")
case a => println("ok2" + a)
case _ => println ("ok3")
}
--->ok2Y
_在scala中的意思: 导包,隐藏类,初始值,函数返回, 参数占位符,模式匹配其他场合
 val list = List("a", "a", "b", "b" )
//    list.groupBy(_) 如果写成这个,编译器无法识别是哪个( f(x): 参数还是x: 参数) 省略的
    println(list.groupBy(x => x)) //Map(b -> List(b, b), a -> List(a, a))

    val list = List(List(1,2), List(1,2))
    println(list.flatMap(x => x)) //List(1, 2, 1, 2)

    val list = List("zs,ls","ww,zl")
    println(list.flatMap(_.split(","))) //List(zs, ls, ww, zl)

匹配类型

匹配对象的任意类型,这样做避免了使用isInstanceOf和asInstanceOf方法

    val a = 3
    val obj = if (a == 1) 5  //int...
    else if (a == 2) "2"    //啥也不是
    else if (a == 3) BigInt(3)  //2147483647
    else if (a == 4) Map("aa" -> 1) //对象是一个字符串-数字的Map集合
    else if (a == 5) Map(1 -> "aa") //对象是一个字符串-数字的Map集合
    else if (a == 6) Array(1, 2, 3) //对象是一个数字数组
    else if (a == 7) Array("aa", 1) //啥也不是
    else if (a == 8) Array("aa") //对象是一个字符串数组

    obj match {
      case a: Int => println("int...")
      //case _ : BigInt => Int.MaxValue
      case b: Map[String, Int] => println("对象是一个字符串-数字的Map集合")
      case c : Map[Int, String] => println("对象是一个数字-字符串的Map集合")
      case d : Array[String] => println("对象是一个字符串数组")
      case e : Array[Int] => println("对象是一个数字数组")
      case _ : BigInt => println(Int.MaxValue)// <=等效于=> case f : BigInt => println(Int.MaxValue)
       // 这里case _ 表示隐藏变量名,即不使用,而不是表示默认匹配,忽略匹配的变量值。
      case _ => println("啥也不是")
    }

 

匹配规则

   for (arr <- Array(Array(0), Array(1, 0), Array(0, 1, 0), Array(1, 1, 0), Array(1, 1, 0, 1))){
      val result = arr match {
        case Array(0) => "0"  //Array(0) 匹配只有一个元素且为0的数组
        case Array(x, y) => x + "=" + y //) 匹配数组有两个元素,并将两个元素赋值为x和y
        case Array(0, _*) => "以0开头和数组" //Array(0,_*) 匹配数组以0开始
        case _ => "什么集合都不是"
      }
      println("result=" + result)
    }
/*    result=0
    result=1=0
    result=以0开头和数组
    result=什么集合都不是
    result=什么集合都不是*/

匹配对象

    // TODO 匹配对象
object Square {
  // unapply可以理解为apply方法的反向操作
  // unapply一般使用在模式匹配中
  def unapply(z: Double): Option[Double] = Some(math.sqrt(z))
  def apply(z: Double): Double = z * z //apply方法用于生成伴生类对象,其实也可以理解对象的工厂
}
    // 模式匹配使用:
    val number: Double = 36.0
    number match {
      case Square(n) => println(n) //6.0
      case _ => println("nothing matched")
    }

 

匹配样例类

 

基本介绍

 

样例类仍然是类

样例类用case关键字进行声明。

样例类是为模式匹配(对象)而优化的类

构造器中的每一个参数都成为val——除非它被显式地声明为var

在样例类对应的伴生对象中提供apply方法让你不用new关键字就能构造出相应的对象

提供unapply方法让模式匹配可以工作

将自动生成toString、equals、hashCode和copy方法(有点类似模板类,直接给生成,供程序员使用)

除上述外,样例类和其他类完全一样。你可以添加方法和字段,扩展它们

 

技术分享图片

Scala模式匹配

原文:https://www.cnblogs.com/shengyang17/p/10645381.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!