Scala 速通语法(十二)| 模式匹配

match 模式匹配

基本介绍

  • Scala 中的模式匹配类似于 Java 中的 switch 语法,但是更加强大
  • 模式匹配语法中,采用 match 关键字声明,每个分支采用 case 关键字进行声明,当需要匹配时,会从第一个 case 分支开始,如果匹配成功,那么执行对应的逻辑代码,如果匹配不成功,继续执行下一个分支进行判断。如果所有 case 都不匹配,那么会执行 case _ 分支,类似于 Java 中 default 语句
    val oper = '-'
    val n1 = 20
    val n2 = 10
    var res = 0
    //说明
    //1. match (类似 java switch) 和case 是关键字
    //2. 如果匹配成功, 则 执行 => 后面的代码块.
    //3. 匹配的顺序是从上到下,匹配到一个就执行对应的 代码


    //4. => 后面的代码块 不要写 break ,会自动的退出 match
    //5. 如果一个都没有匹配到,则执行 case _ 后面的代码块
    oper match {
      case '+' => res = n1 + n2
      case '-' => res = n1 - n2
      case '*' => res = n1 * n2
      case '/' => res = n1 / n2
      case _ => println("oper error")
    }
    println("res=" + res)

守卫

  • 如果想要表达匹配某个范围的数据,就需要在模式匹配中增加条件守卫
  // 说明..
  // 如果 case 后有 条件守卫即 if ,那么这时的 _ 不是表示默认匹配
  // 表示忽略 传入 的 ch
  case _ if ch.toString.equals("3") => digit = 3
  case _ if (ch > 1110 || ch < 120) => println("ch > 10")

模式中的变量

  • 如果在 case 关键字后跟变量名,那么 match 前表达式的值会赋给那个变量
  ch match {
  case '+' => println("ok~")
  // 下面 case mychar 含义是 mychar = ch
  case mychar => println("ok~" + mychar)
  case _ => println ("ok~~")
}

类型匹配

  • 可以匹配对象的任意类型,这样做避免了使用 isInstanceOf 和 asInstanceOf 方法
val result = obj match {
case a: Int => a
  case b: Map[String, Int] => "对象是一个字符串-数字的 Map 集合"
  case c: Map[Int, String] => "对象是一个数字-字符串的 Map 集合"
}

类型匹配注意事项

  • Map[String, Int] 和 Map[Int, String]是两种不同的类型,其它类推
  • 在进行类型匹配时,编译器会预先检测是否有可能的匹配,如果没有则报错
  val result = obj match {
    case i : Int => i
  } 
  //case i : Int => i 表示 将 i = obj (其它类推),然后再判断类型
  • 如果 case _ 出现在 match 中间,则表示隐藏变量名,即不使用,而不是表示默认匹配
  • unapply 方法是对象提取器

for循环模式匹配

for ((k, v) <- map if v >= 1) {
  println(k + " ---> " + v)
}

样例(模板)类

    1. 样例类仍然是类
    1. 样例类用 case 关键字进行声明。
    1. 样例类是为模式匹配而优化的类
    1. 构造器中的每一个参数都成为 val——除非它被显式地声明为 var(不建议这样做)
    1. 在样例类对应的伴生对象中提供 apply 方法让你不用 new 关键字就能构造出相应的对象
    1. 提供 unapply 方法让模式匹配可以工作
    1. 将自动生成 toString、equals、hashCode 和 copy 方法(有点类似模板类,直接生成)
    1. 除上述外,样例类和其他类完全一样。你可以添加方法和字段,扩展它们

abstract class Amount
case class Dollar(value: Double) extends Amount //样例类
case class Currency(value: Double, unit: String) extends Amount //样例类
case object NoAmount extends Amount //样例类

case 语句的中置(缀)表达式

List(1, 3, 5, 9) match { //测试
  //1.两个元素间::叫中置表达式,至少 first,second 两个匹配才行.可以多 但最后一个匹配剩余的
  //2.first 匹配第一个 second 匹配第二个,third匹配第三个 rest 匹配剩余部分(5,9)
    case first :: second :: third :: rest => println(first + " " + second + " " + " " + third + rest.length + " " + rest) //
    case _ => println("匹配不到...")
}

//结果: 1 3  5 1 List(9)

密封类

  • 如果让case类的所有子类都必须声明在该类的相通源文件中定义 可以将样例类的通用超类声明为sealed,这个超类称之为密封类
  • 密封类不能再其他文件中定义子类
posted @ 2021-11-08 14:58  —清风碎心—  阅读(75)  评论(0编辑  收藏  举报