Scala模式匹配

模式匹配

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

1、基本语法

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

  /**
   * 模式匹配简单定义与使用
   */
  def pattern_match_define(): Unit = {
    val x: Int = 2
    val y: String = x match {
      case 1 => "one"
      case 2 => "two"
      case 3 => "three"
      case _ => "other"
    }
    println(y)

    val a = 256
    val b = 213

    //使用模式匹配实现简单二元运算
    def matchDualOp(op: Char) = op match {
      case '+' => a + b
      case '-' => a - b
      case '*' => a * b
      case '/' => a / b
      case '%' => a % b
      case _ => -1
    }

    println(matchDualOp('-'))
  }

2、模式守卫

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

  /**
   * 模式守卫
   */
  def pattern_match_protector(): Unit = {
    def abs(num: Int): Int = {
    num match {
      case i if i >= 0 => i
      case i if i < 0 => -i
    }
    }
    
    println(abs(-1010))
  }

3、常量匹配

  def match_constants(): Unit = {


    def func(x: Any): String = {
      x match {
        case 1 => "int"
        case "scala" => "string"
        case true => "boolean"
        case _ => "other"
      }
    }

    println(func("scala"))
    println(func(1.23f))
  }

4、类型匹配

  • Scala 类型匹配jvm中有泛型擦除,对于List类型判断,无法准确区分泛型的不同。因此,List[String] List[Int]都能匹配上
  • 需要注意的是,数组array不存在泛型擦除
  def match_type(): Unit = {
//    def func(x: Any): String = x match {
//      case i: Int => "int"
//      case s: String => "string"
//      case d: Double => "double"
//      case arr:Array[Int] => "Arr"
//      case _ => "other"
//    }

    val func: Any => String = x => x match {
      case i: Int => "int"
      case s: String => "string"
      case d: Double => "double"
      case list: List[String] => "list"
      case arr:Array[Int] => "Arr"
      case _ => "other"
    }

    println(func(1001))
    println(func(1.23))
    println(func(1.9f))
    println(func(List("scala", "java")))
    println(func(List(1,2,3,4,5)))
    println(func(Array(1,2,3,4,5)))
    println(func(Array("scala", "java")))
  }

5、匹配数组

  def match_arr(): Unit = {

    for (arr <- List(
      Array(1,2,3,4,5),
      Array(1,0,0,1),
      Array(1,3,5),
      Array("scala", 2023)
    )) {
      val result = arr match {
        case Array(1,0,0,1) => "1001"
        case Array(a,b,c) => "3 element araay"
        case Array(1, _*) => "start with 1"
        case Array(a, 2023) => "the second element is 2023"
        case _ => "other array"
      }
      println(result)
    }
  }

6、匹配列表

  def match_list(): Unit = {
    //方式一
    for(list <- List(
      List(0),
      List(0,1,1,0),
      List(1,0,1),
      List(1,0,0,0,1),
      List(1,2,3,4,5,6,7,8)
    )) {
      val result = list match {
        case List(0) => "list 0"
        case List(a,b,c) => "3 elements list"
        case List(0, _*) => "the list of start with 0"
        case _ => "other list"
      }
      println(result)
    }

    println("===================================")

    //方式二:
    val list2  = List(1,2,3,4,5,6,7)
    list2 match {
      case first :: second :: rest => println(s"first=${first}, second=${second}, rest=$rest")
    }
  }

7、元组匹配

  def match_tuple(): Unit = {
    for(tuple <- List(
      (1,2),
      (1,2,3,4),
      (2,0,2,3),
      ("scala", "java", 2023)
    )) {
      val result = tuple match {
        case (a,b) => s"a=${a}, b=$b"
        case (2,_) => "(0, _)"
        case (a, "java", _) => "tuple3"
        case _ => "other tuple"
      }

      println(result)
    }
  }

拓展

  def match_tuple_extend(): Unit = {
    //1、在变量声明时匹配
    val (x, y) = ("scala", 2023)
    println(s"x=${x}, y=$y")

    val List(first, second, _*) = List(1,2,3,4,5,65,6)
    println(s"first=${first}, second=${second}")

    val fir :: sec :: rest = List(123, 546, 789, 1001, 2023)
    println(s"fir=${fir}, sec=$sec, rest=$rest")


    //2、在for推导式中进行模式匹配
    val tupleList = List((1, "a"), (2, "b"), (3, "c"))
//    for(element <- tupleList) {
//      println(element._1 + " " + element._2)
//    }


//    for ((code, word) <- tupleList) {
//      println(s"code:${code}, word=${word}")
//    }


    //3、可以不考虑某个位置的变量,只遍历key或者value
//    for((code, _) <- tupleList) {
//      println(s"code=${code}, word=${_}")
//    }

    //4、可以指定某个位置的值必须是多少
    for ((code, "c") <- tupleList) {
      println(code)
    }

  }

8、匹配对象和样例类

def match_obj_caseClass(): Unit = {
  //1、普通类匹配
  val user = new User601("merlin", 23)
  //针对对象实例的内容进行匹配
  val result = user match {
    case User601("merlin", 23) => "same user"
    case _ => "different user"
  }
  println(result)

  println("==================================")

  //2、样例类匹配
  val student = new Student601("scala", 2023)

  val result2 = student match {
    case Student601("scala", 2024) => "same student"
    case _ => "different student"
  }

  println(result2)
}


//定义类
class User601(val name: String, val age: Int)

//伴生对象
object User601 {

  def apply(name: String, age: Int): User601 = new User601(name, age)
  //必须实现一个unapply方法,用来对对象属性进行拆解
  def unapply(user: User601): Option[(String, Int)] = {
    if (user == null) {
      None
    } else {
      Some((user.name, user.age))
    }
  }
}


/**
 * 样例类
 *  - 主构造器中的所有参数默认都是val
 *  - 样例类对应的伴生对象,以及apply、unapply全部自动生成
 */
case class Student601(val name: String, val age: Int)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值