学习链接:https://www.bilibili.com/video/BV1Xh411S7bP?p=125&spm_id_from=pageDriver
1 基本语法
所有case都不匹配,执行case 分支,类似default。没有case 分支,抛出MatchError
每个case中,不需要使用break语句,自动中断case
match case语句可以匹配任何类型
=> 后面的代码块,直到下一个 case 语句之前的代码是作为一个整体执行,可以
使用{}括起来,也可以不括
object Test01_PatterMatchBase {
def main(args: Array[String]): Unit = {
// 1. 基本定义语法
val x: Int = 2
val y: String = x match {
case 1 => "one"
case 2 => "two"
case 3 => "three"
case _ => "other" // case _ 相当于default,若没有case _分支,都不匹配,MatchError
}
println(y)
// 2. 示例:用模式匹配实现简单二元运算
val a = 25
val b = 13
def matchDualOp(op: Char) = op match {
case '+' => a + b
case '-' => a - b
case '*' => a * b
case '/' => a / b
case '%' => a % b
case _ => "非法运算符"
}
println(matchDualOp('+'))
}
}
2 模式守卫
如果想要表达匹配某个范围的数据,需要在模式匹配中增加条件守卫
// 模式守卫
// 求一个整数的绝对值
def abs(num: Int): Int = {
num match {
case i if i >= 0 => i
case i if i < 0 => -i
}
}
println(abs(67)) // 67
println(abs(0)) // 0
println(-24) // -24
3 模式匹配类型
3.1 匹配常量
object Test02_MatchTypes {
def main(args: Array[String]): Unit = {
// 1. 匹配常量
def describeConst(x: Any): String = x match {
case 1 => "Num one"
case "hello" => "String hello"
case true => "Boolean true"
case '+' => "Char +"
case _ => ""
}
println(describeConst("hello"))
}
}
3.2 匹配类型
// 2. 匹配类型
def describeType(x: Any): String = x match {
case i: Int => "Int " + i
case s: String => "String " + s
case list: List[String] => "List " + list
case array: Array[Int] => "Array[Int] " + array.mkString(",")
case a => "Something else:" + a
}
println(describeType(List(2, 3))) // 泛型擦除
println(describeType(Array(2, 3))) // 没有泛型擦除
println(describeType(Array("aaa", "vvv"))) // Something else:[Ljava.lang.String;@6bdf28bb
3.3 匹配数组
// 3. 匹配数组
for (arr <- List(
Array(0),
Array(1),
Array(0, 1, 0),
Array(1, 1, 0),
Array(2, 3, 7, 15),
Array("hello", 20, 30)
)) {
val result = arr match {
case Array(0) => "0"
case Array(1, 0) => "Array(1, 0)"
case Array(x, y) => "Array: " + x + ", " + y // 匹配两元素数组
case Array(0, _*) => "以0开头的数组"
case Array(x, 1, z) => "中间为1的3元素数组"
case _ => "something else"
}
println(result)
3.4 匹配列表
// 4. 匹配列表
// 方式一
for (list <- List(
List(0),
List(1, 0),
List(0, 0, 0),
List(1, 1, 0),
List(88)
)) {
val result = list match {
case List(0) => "0"
case List(x, y) => "List(x, y): " + x + ", " + y
case List(0, _*) => "List(0, ...)"
case List(a) => "List(a): " + a
case _ => "something else"
}
println(result)
/*
0
List(x, y): 1, 0
List(0, ...)
something else
List(a): 88
*/
}
// 方式二
val list = List(1, 2, 5, 7, 24)
list match {
case first :: second :: rest => println(s"first: $first, second: $second, rest: $rest")
case _ => println("something else")
}
// first: 1, second: 2, rest: List(5, 7, 24)
3.5 匹配元组
// 5. 匹配元组
for (tuple <- List(
(0, 1),
(0, 0),
(0, 1, 0),
(0, 1, 1),
(1, 23, 56),
("hello", true, 0.5)
)) {
val result = tuple match {
case (a, b) => "" + a + ", " + "b"
case (0, _) => "(0, _) "
case (a, 1, _) => "(a, 1, _) " + a
case (x, y, z) => "(x, y, z) " + x + " " + y + " " + z
case _ => "something else"
}
println(result)
}
3.6 匹配对象及样例类
object Test04_MatchObject {
def main(args: Array[String]): Unit = {
val student = new Student("aaa", 28)
// 针对对象实例的内容进行匹配
val result = student match {
case Student("aaa", 28) => "aaa, 28"
case _ => "else"
}
println(result) // aaa, 28
}
}
// 定义类
class Student(val name: String, val age: Int)
// 定义伴生对象
object Student {
def apply(name: String, age: Int): Student = new Student(name, age)
// 必须实现一个unapply方法,用来对对象属性进行拆解
def unapply(student: Student): Option[(String, Int)] = {
if(student == null) {
None
} else {
Some((student.name, student.age))
}
}
}
样例类:
object Test05_MatchCaseClass {
def main(args: Array[String]): Unit = {
val student = new Student1("aaa", 18)
// 针对对象实例的内容进行匹配
val result = student match {
case Student1("aaa", 28) => "aaa, 28"
case _ => "else"
}
println(result) // else
}
}
// 定义样例类
case class Student1(name: String, age: Int)
4 偏函数中的模式匹配
偏函数定义
val second: PartialFunction[List[Int], Option[Int]] = {
case x :: y :: _ => Some(y)
}
object Test06_PartialFunction {
def main(args: Array[String]): Unit = {
val list: List[(String, Int)] = List(("a", 12), ("b", 35), ("c", 27), ("a", 13))
// 1. map转换,实现key不变,value 2倍
val newList = list.map(tuple => (tuple._1, tuple._2 * 2))
// 2. 用模式匹配对元组元素赋值,实现功能
val newList2 = list.map(
tuple => {
tuple match {
case (word, count) => (word, count * 2)
}
}
)
// 3. 省略lambda表达式的写法,进行简化
val newList3 = list.map {
case (word, count) => (word, count * 2)
}
println(newList) // List((a,24), (b,70), (c,54), (a,26))
println(newList2) // List((a,24), (b,70), (c,54), (a,26))
println(newList3) // List((a,24), (b,70), (c,54), (a,26))
// 偏函数的应用,求绝对值
// 对输入数据分为不同的情形:正、负、0
val positionAbs: PartialFunction[Int, Int] = {
case x if x > 0 => x
}
val negativeAbs: PartialFunction[Int, Int] = {
case x if x < 0 => -x
}
val zeroAbs: PartialFunction[Int, Int] = {
case 0 => 0
}
def abs(x: Int): Int = (positionAbs orElse negativeAbs orElse zeroAbs)(x)
println(abs(-67))
println(abs(35))
println(0)
}
}