a30_scala 模式匹配

scala outline

scala outline

scala match 代码示例

  1. java模式匹配使用的关键字为switch-case,scala是match-case

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

  3. 如果所有case都不匹配,那么会执行case _ 分支,类似于Java中default语句,若此时没有case _ 分支,那么会抛出MatchError

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

  def main(args: Array[String]): Unit = {
    var a: Int = 10
    var b: Int = 20
    var op: Char = '+'
    //模式匹配是有返回值
    var res = op match {
      case '+' => a + b
      case '-' => a - b
      case _ => "默认情况"
    }
    println(res)
  }

scala 模式守卫

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

通过模式守卫 求一个整数的绝对值

  def main(args: Array[String]): Unit = {
    def abs(num: Int): Int = {
      num match {
        case x: Int if x >= 0 => x
        case x: Int if x < 0 => -x
      }
    }

    println(abs(-7))
  }

scala 模式匹配

  • 匹配常量

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

  def main(args: Array[String]): Unit = {
    def f(e: Any): Any = {
      e match {
        case "hello" => "String"
        case true => "Boolean"
        case '+' => "op"
        case 5 => "Int"
        case _ => "默认情况"
      }
    }

    println(f("hello"))
  }
  • 匹配类型

需要进行类型判断时,可以使用isInstanceOf[T]和asInstanceOf[T],也可使用模式匹配实现同样的功能

  def main(args: Array[String]): Unit = {
    def f(e: Any): Any = {
      e match {
        case s: String => "String"
        case flag: Boolean => "Boolean"
        case m: List[String] => "List"
        case a: Array[Int] => "Array[Int]"
        case d => "something else" + d
      }
    }
    // 泛型擦除,在匹配的时候,和泛型无关(只限于集合,排除数组)
    println(f(List(2, 3))) // 输出 List
  }
  • 匹配数组 匹配列表 匹配元组

3者之间非常类似,只演示匹配数组

    val list = List(Array(0), Array("hello", 90), Array(0, 1, 0), Array(1, 1, 0))
    for (arr <- list) {
      val res: String = arr match {
        case Array(0) => "0"
        case Array(x, y) => x + "," + y
        case Array(0, _*) => "以0开头的数组"
        case _ => "something else"
      }
      println(res)
    }
  }

输出

0
hello,900开头的数组
something else
  • 匹配对象


object Test02 {
  def main(args: Array[String]): Unit = {
    val xiaoming: User = new User("老王", 55)
    val res = xiaoming match {
      case User("老王", 55) => "Yes" // 底层会调用unapply(),然后把小明作为参数传过去,获取小明的属性,然后会和老王进行比较
      case _ => "NO"
    }
    println(res)
  }
}

class User(var name: String, var age: Int) {}

object User {
  // 根据属性创建对象(此处没有用)
  def apply(name: String, age: Int): User = new User(name, age)

  // 根据对象获取属性
  def unapply(arg: User): Option[(String, Int)] = {
    if (arg == null)
      return None
    else {
      return Some(arg.name, arg.age)
    }
  }
}

可用case关键字来简化上述代码,参考样例类

  • 样例类

  1. 样例类用 case 关键字进行声明
  2. 样例类仍然是类,和普通类相比,只是其自动生成了伴生对象,并且伴生对象中自动提供了一些常用的方法,如apply、unapply、toString、equals、hashCode和copy
  3. 样例类是为模式匹配而优化的类,因为其默认提供了unapply方法,所以样例类可以直接使用模式匹配,而无需自己实现unapply方法
  4. 构造器中的每一个参数都成为val,除非它被显式地声明为var(不建议这样做)

参考匹配对象

object Test02 {
  def main(args: Array[String]): Unit = {
    val laowang: User = new User("老王", 55)
    val res = laowang match {
      case User("老王", 55) => "Yes"
      case _ => "NO"
    }
    println(res) // Yes
  }
}

case class User(var name: String, var age: Int) {}
  • 中置(缀)表达式

两个元素间用::叫中置表达式

  def main(args: Array[String]): Unit = {
    List(1, 3, 5, 9) match { //修改并测试
      // 1.两个元素间::叫中置表达式,至少 first,second 两个匹配才行.
      // 2.first 匹配第一个 second 匹配第二个, rest 匹配剩余部分(5,9)
      case first :: second :: rest => println(first + " " + second + " " + rest)  // 1 3 List(5, 9)
      case _ => println("not match!")
    }
  }

scala case 简化小案例

实现wordcount

  def main(args: Array[String]): Unit = {
    val list: List[(String, Int)] = List(("a", 1), ("b", 2), ("c", 3))
    val newList: List[(String, Int)] = list.map((t: (String, Int)) => {
      t match {
        case (word, count) => (word, count * 2)
      }
    })
    println(newList) // 输出 List((a,2), (b,4), (c,6))
  }

选中 部分是一个匿名函数,匿名函数可以简化

在这里插入图片描述

简化后的代码

  1. 如果一个函数参数的列表中只有一个参数,那么参数列表的小括号可以花括号代替
  2. 如果匿名函数中,使用模式匹配case,要求必须用花括号括起来
list.map { case (word, count) => (word, count * 2) }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值