介绍
模式匹配,写法类似 JAVA 的 switch 语句,但不需要 break
功能非常强大,如:
- 判断值
- 判断类型
语法
val res = 变量/常量 match {
case 匹配值1 => 返回值1
case 匹配值2 => 返回值2
...
}
匹配字面值
匹配字面值,类似 java 的 switch 语句
val i = 5
val res = i match {
case 1 => "星期一"
case 2 => "星期二"
case 3 => "星期三"
case 4 => "星期四"
case 5 => "星期五"
case 6 => "星期六"
case 7 => "星期日"
case _ => "无效日期" // 类似 java switch 的 default
}
println(res)
执行结果:
星期五
总结
所有
case都不匹配,则 匹配case _,类似 javaswitch语句的default。如果没有case _会报错与 java
switch语句不同,case后不需要break
搭配函数、方法
将上面的代码 封装 成 函数 或 方法,隐藏细节,调用起来更加方便
def main(args: Array[String]): Unit = {
def week(i:Int) : String = i match {
case 1 => "星期一"
case 2 => "星期二"
case 3 => "星期三"
case 4 => "星期四"
case 5 => "星期五"
case 6 => "星期六"
case 7 => "星期日"
case _ => "无效日期"
}
println( week(1))
println( week(5))
println( week(7))
println( week(10))
}
匹配不同的类型 的字面值
可以匹配 任意类型的 字面值。if 语句 或 java 的 switch 语句,都没有此功能
// 由于可传入不同类型的形参,所以形参类型是 Any
def m(x:Any) = x match {
case "one" => "字符串类型"
case 1 => "整型"
case 1.1 => "浮点类型"
case true => "布尔类型"
case _ => "未知类型"
}
println( m("one"))
println( m(1))
println( m(1.1))
println( m(true))
println( m( '汉' ))
执行结果:
字符串类型
整型
浮点类型
布尔类型
未知类型
匹配类型
注意:这里是 匹配类型,不是匹配字面值
def main(args: Array[String]): Unit = {
def getType(x: Any) = x match {
case i: String => "字符串类型"
case i: Int => "整型"
case i: Double => "浮点类型"
case i: Boolean => "布尔类型"
case _ => "未知类型"
}
println(getType("one"))
println(getType(1))
println(getType(1.1))
println(getType(true))
}
集合的泛型会擦除(数组不会擦除)
def main(args: Array[String]): Unit = {
// 匹配类型
def getType(i: Any): String = i match {
// List 后面的 必须有泛型,编译时会擦除泛型
case i: List[Int] => "List,泛型是Int"
// Array 后面的 必须有泛型
case i: Array[Int] => "Array,泛型是Int"
case _ => "未知类型"
}
//未知类型,数组不会发生擦除泛型
println("res:" + getType( Array("李雷","韩梅梅") ) )
//Array,泛型是Int
println("res:" + getType( Array(1,200)) )
//List,泛型是Int,List 会发生擦除泛型
println("res:" + getType( List("李雷", "韩梅梅")))
//List,泛型是Int,泛型是Int
println("res:" + getType( List(1, 200)))
}
解释:对于 集合 来说,泛型会被擦除,所以会导致 匹配不正确。数组不会擦除
集合擦除泛型的原因:
反编译如下:
匹配数组
根据传入数组的元素,进行匹配
def main(args: Array[String]): Unit = {
def m(arr:Array[Int]) = arr match {
case Array(1,2,3) => "一共3个元素,且是:1、2、3"
case Array(1,2,3, x) => "一共4个元素,最后一个元素可以是任意整数"
case Array(x ,3, y) => "一共3个元素,第二个元素是3"
case Array(3, _*) => "第一个元素是3,后面可以是任意整数,*表示任意个元素"
case _ => "未知"
}
println( m(Array(1,2,3)))
println( m(Array(1,2,3,100)))
println( m(Array(1,3,100)))
println( m(Array(3,40,100)))
}
匹配列表
功能同 匹配数组
def main(args: Array[String]): Unit = {
def m(arr: List[Int]) = arr match {
case List(1, 2, 3) => "一共3个元素,且是:1、2、3"
case List(1, 2, 3, x) => "一共4个元素,最后一个元素可以是任意整数"
case List(x, 3, y) => "一共3个元素,第二个元素是3"
case List(3, _*) => "第一个元素是3,后面可以是任意整数,且长度任意"
case _ => "未知"
}
println(m(List(1, 2, 3)))
println(m(List(1, 2, 3, 100)))
println(m(List(1, 3, 100)))
println(m(List(3, 40, 100)))
}
匹配元组
功能同 匹配数组
def main(args: Array[String]): Unit = {
def m(arr: Any ) = arr match {
case (1, 2, 3) => "一共3个元素,且是:1、2、3"
case (1, 2, 3, x) => "一共3个元素,最后一个元素可以是任意整数"
case (x, 3, y) => "一共3个元素,第二个元素是3"
case _ => "未知"
}
println(m((1, 2, 3)))
println(m((1, 2, 3, 100)))
println(m((1, 3, 100)))
println(m((3, 40, 100))) // 未知
}
匹配 for 表达式
使用 for 语句,查找集合中的某个元素时,可以用模式匹配简化写法
在 List 中,找出身高(第二个元素)是 170 的姓名
普通写法:
def main(args: Array[String]): Unit = {
val list = List( ("李雷",183),("韩梅梅",165),("lucy",170),("lili",170))
// 普通写法
for (item <- list) {
if ( item._2 == 170) {
println(item._1)
}
}
模式匹配:
def main(args: Array[String]): Unit = {
val list = List( ("李雷",183),("韩梅梅",165),("lucy",170),("lili",170))
for( ( x,170) <- list ){
println(x)
}
}
模式守卫
匹配变量,与 java 的 switch 相比,可以实现 根据分数返回 优、良、中、差、不及格
def main(args: Array[String]): Unit = {
def score(i: Int): String = i match {
case i if i>=90 => "优"
case i if i>=80 => "良"
case i if i>=70 => "中"
case i if i>=60 => "差"
case _ => "不及格"
}
println(score(92))
println(score(85))
println(score(77))
println(score(62))
println(score(35))
}
多行代码可以用 {}
如果 case => 后 有多行代码,可以用 {} 包裹
val i = 5
val res = i match {
case 1 => "星期一"
case 2=> {
1 + 1 // 如果有多行代码可以用 {}
"星期二"
}
case 3 => "星期三"
case 4 => "星期四"
case 5 => "星期五"
case 6 => "星期六"
case 7 => "星期日"
case _ => "无效日期"
}
println(res)
