Scala模式匹配

注:该文章只标注常用以及本人不熟悉的知识点(也就是说,不全)。望xdm海涵

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


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

  val a = 10
  val b = 20
  val operator: Char = 'd'
  val result = operator match {
    case '+' => a + b
    case '-' => a - b
    case '*' => a * b
    case '/' => a / b
    case _ => "illegal"
  }
  println(result)

  1. 如果所有 case 都不匹配,那么会执行 case _ 分支,类似于 Java 中default 语句, 若此时没有case _ 分支,那么会抛出MatchError。
  2. 每个case 中,不需要使用break 语句,自动中断case。
  3. match case 语句可以匹配任何类型,而不只是字面量。
  4. => 后面的代码块,直到下一个 case 语句之前的代码是作为一个整体执行,可以使用{}括起来,也可以不括。

模式守卫

和循环守卫类似

def abs(x: Int) = x match {
    case i: Int if i >= 0 => i 
    case j: Int if j < 0 => -j
    case _ => "type illegal"
}

模式匹配类型

1.匹配常量

Scala 中,模式匹配可以匹配所有的字面量,包括字符串,字符,数字,布尔值等等

def describe(x: Any) = x match { 
    case 5 => "Int five"
    case "hello" => "String hello" 
    case true => "Boolean true" 
    case '+' => "Char +"
}

2.匹配数组

scala 模式匹配可以对集合进行精确的匹配,例如匹配只有两个元素的、且第一个元素为 0 的数组。

//匹配 Array(0) 这个数组
case Array(0) => "0" 

//匹配有两个元素的数组,然后将将元素值赋给对应的 x,y
case Array(x, y) => x + "," + y 

//匹配以 0 开头和数组
case Array(0, _*) => "以 0 开头的数组" 

3.匹配元组

//对一个元组集合进行遍历
for (tuple <- Array((0, 1), (1, 0), (1, 1), (1, 0, 2))) {
    val result = tuple match {
        case (0, _) => "0 ..." //是第一个元素是 0 的元组
        case (y, 0) => "" + y + "0" // 匹配后一个元素是 0 的对偶元组
        case (a, b) => "" + a + " " + b case _ => "something else" //默认
    }
    println(result)
}

4.匹配对象及样例类

匹配对象

class User(val name: String, val age: Int)
object User{
    def apply(name: String, age: Int): User = new User(name, age) 
    def unapply(user: User): Option[(String, Int)] = {
    if (user == null)
        None 
    else
        Some(user.name, user.age)
    }
}

object TestMatchUnapply {
    def main(args: Array[String]): Unit = {
        val user: User = User("zhangsan", 11) 
        val result = user match {
            case User("zhangsan", 11) => "yes"
            case _ => "no"
        }

        println(result)
    }
}

1.val user = User("zhangsan",11),该语句在执行时,实际调用的是 User 伴生对象中的apply 方法,因此不用 new 关键字就能构造出相应的对象。

2.当将 User("zhangsan", 11)写在 case 后时[case User("zhangsan", 11) => "yes"],会默认调用 unapply 方法(对象提取器),user 作为 unapply 方法的参数,unapply 方法将 user 对象的 name 和 age 属性提取出来,与User("zhangsan", 11)中的属性值进行匹配

3.case 中对象的 unapply 方法(提取器)返回 Some,且所有属性均一致,才算匹配成功,属性不一致,或返回 None,则匹配失败。

4.若只提取对象的一个属性,则提取器为 unapply(obj:Obj):Option[T]

5.若提取对象的多个属性,则提取器为 unapply(obj:Obj):Option[(T1,T2,T3…)]

6.若提取对象的可变个属性,则提取器为 unapplySeq(obj:Obj):Option[Seq[T]] 

样例类

语法:case class Person (name: String, age: Int)

说明:

        样例类仍然是类,和普通类相比,只是其自动生成了伴生对象,并且伴生对象中自动提供了一些常用的方法,如 applyunapplytoString、equals、hashCode 和 copy。

        样例类是为模式匹配而优化的类,因为其默认提供了 unapply 方法,因此,样例类可以直接使用模式匹配,而无需自己实现 unapply 方法。

        构造器中的每一个参数都成为 val,除非它被显式地声明为 var(不建议这样做)

case class User(name: String, age: Int)

object TestMatchUnapply {
    def main(args: Array[String]): Unit = { 
        val user: User = User("zhangsan", 11) 
        val result = user match {
            case User("zhangsan", 11) => "yes" 
            case _ => "no"
        }

        println(result)
    }
}

总之Scala中的模式匹配可以匹配各种类型的元素

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值