Scala总结之模式匹配
采用 match 关键字声明,每个分支采用 case 关键字进行声明,当需要匹配时, 会从第一个 case 分支开始,如果匹配成功,那么执行对应的逻辑代码,如果匹配不成功,继续执行下一个分支进行判断。如果所有 case 都不匹配,那么会执行 case _ 分支,类似于 Java 中 default 语句。
在java代码规范中,有一条规则是说“当分支数大于2时,选用switch case,不要用if else”。在Scala语言中,没有java中的switch case语法,但是引入了更强大的match case语法来满足这点。除了能够代替java switch case语法功能,switch case还可以匹配对象、范围匹配、类型匹配等等功能。
相同点
1、 都是用来避免多分支的情况下,去使用很多个if else分支,代码可以更加的清晰。
不同点
1、 scala中match case,不存在case击穿,不需要使用“break”(scala中也没有break关键字)。而java case分支不加break,就会出现case击穿现象。
2、 Java 中 case后面只能放int、byte、char、short、string、枚举类型,scala不限于上述范围,支持scala collection、对象、样例类等,scala中支持的类型匹配,避免在代码中使用isInstanceOf、asInstanceOf方法。类型匹配代码说明如下:
val i = 1;
val value=if(i==0){
Array("zsf")
}else if(i==1){
Map("zsf"->"zsf")
}
val result = value match {
case a:Array[String] => 1
case b:Map[String,String] => 2
case b:Map[Int,String] => 3
case b:List[String] => 4
case _ => 0
}
println(s"result is :$result")
运行结果如下:
result is :2
3、 scala中用_表示默认分支,java中用default来表示默认分支。当case _分支位于第一个case分支时,后面的case分支永远不能执行到。
验证代码如下:
val value = "zsf"
val result = value match {
case _ => "unknow value"
case "zsf" => "match is zsf"
}
println(s"result is $result")
输出结果:
result is unknow value
4、 scala中如果没有一个分支能够匹配上,会抛出“scala.MatchError”,java中不会有异常抛出,程序正常结束。
5、 scala中的match case是一个有返回值的语句,因为scala match case是一个表达式。
6、 利用守卫,scala中的match case可以达到范围匹配的效果。下面代码便可实现10-20时匹配第一个分支,小于10时匹配第二个分支的效果。
val value =19
value match {
case _ if value>10 &&value <20 =>println("10~20")
case _ if value<10=>println("<10")
}
7、 scala支持匹配对象
对象匹配,什么才算是匹配呢?规则如下:
a) case 中对象的unapply方法(对象提取器)返回Some集合则为匹配成功
b) 返回 None 集合则为匹配失败。
下面定义了两个自定义类——woman、man,他们的区别在于woman的提取器unapply返回None,而man的提取器返回Some。
class Woman(val name:String){
}
object Woman{
def unapply(man: Man): Option[(String, Int)] = {
None
}
}
class Man(val name:String,val age:Int){}
object Man{
def unapply(man: Man): Option[(String, Int)] = {
Some(man.name,man.age)
}
def apply(name: String, age: Int): Man = new Man(name, age)
}
试验代码
package base
object ObjectMatch {
def main(args: Array[String]): Unit = {
val womanResult = new Woman("xh") match {
case Woman(name) => s"woman is $name"
case Man(name,age) => s"name is $name;age is $age"
case List(1,a) => s"1打头的,第二个元素是$a 的list"
case _ =>"no case to match."
}
val manResult = new Man("xh",29) match {
case Woman(name) => s"woman is $name"
case Man(name,age) => s"name is $name;age is $age"
case List(1,a) => s"1打头的,第二个元素是$a 的list"
case _ =>"no case to match."
}
println(s"womanResult is $womanResult")
println(s"manResult is $manResult")
}
}
验证结果
womanResult is no case to match.
manResult is name is xh;age is 29