模式匹配
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)