scala模式匹配
模式匹配包含了一系列备选项,每个都开始于关键字 case。每个备选项都包含了一个模式及一到多个表达式。箭头符号 => 隔开了模式和表达式。
match 对应 Java 里的 switch,但是写在选择器表达式之后。Scala的模式匹配除了可以对值进行匹配之外,还可以对类型进行匹配、对Array和List的元素情况进行匹配、对case class进行匹配、甚至对有值或没值(Option)进行匹配。
match 表达式通过以代码编写的先后次序尝试每个模式来完成计算,只要发现有一个匹配的case,剩下的case不会继续匹配。
对于Spark来说,Scala的模式匹配功能也是极其重要的,在spark源码中大量地使用了模式匹配功能。
1.基本语法
match case语法最基本的应用,就是对变量的值进行模式匹配
def match1(x:Int):String=x match{
case 1=>"one"
case 2=>"two"
case _=>"other" //其他选项用 "_"表示
}
println(match1(1)) //输出one
2.类型匹配
Scala模式匹配可以直接对类型匹配
def match1(x:Any) =x match{
case i:Int =>println("输入的值类型为Int类型,值为:"+i)
case j:String =>println("输入的值类型为String类型,值为:"+j)
case _ =>println("输入类型未知")
}
match1(2) //输入得值类型为Int类型,值为:2
案例:对异常进行匹配
def excepetionmatch(e:Exception)=e match{
case e1:IOException => println("error,IOException")
case e2:NullPointerException=> println("error,NullPointerException")
case e3:ClassNotFoundException=> println("error,ClassNotFoundException")
case _:Exception=> println("don't know")
}
excepetionmatch(new IllegalArgumentException)
3.使用if守卫
Scala的模式匹配语法,有一个特点在于,可以在case后的条件判断中,不仅仅只是提供一个值,而是可以在值后面再加一个if守卫,进行双重过滤
def match1(name:String,score:String) =score match{
case "A"=> println("perfect")
case "B"=> println("good")
case "C"=> println("just so so")
case _ if name=="Li" => println(name+",请再接再厉")
case _=> println("未及格")
}
match1("Li","F")
/* Scala的模式匹配语法,有一个特点在于,可以将模式匹配的默认情况,下划线,替换为一个变量名,
此时模式匹配语法就会将要匹配的值赋值给这个变量,从而可以在后面的处理语句中使用要匹配的值
但是对于下划线_这种情况,所有不满足前面的case的值,都会进入_这种默认情况进行处理,
此时如果我们在处理语句中需要拿到具体的值进行处理,那就需要使用这种在模式匹配中进行变量赋值的语法.*/
def match2(name:String,score:String) =score match{
case "A"=> println("perfect")
case "B"=> println("good")
case "C"=> println("just so so")
case _ if name=="Li" => println(name+",请再接再厉")
case _score=> println(name+"get "+_score+" 未及格,") //变量赋值
}
match2("Li","D")
4.对Array和List的元素进行模式匹配
对Array进行模式匹配,分别可以匹配带有指定元素的数组、匹配指定个数元素的数组、以某元素开头的数组
def match1(arr: Array[String])=arr match {
case Array("Mike") => println("Hello,Mike")
case Array(s1,s2,s3) => println("hello"+","+s1+","+s2+","+s3)
case Array("Mike",_*) => println("hi")
case _ => println("hi,what's your name")
}
var arr1=Array("Mike","Jim","Lucy","jeson") //定义Array
var arr2=Array("Mike")
var arr3=Array("Jim","Mike","Lucy")
var arr4=Array("Jim","Lucy","Mike","jeson")
match1(arr1) //对以mike开头的数组匹配 输出:hi
match1(arr2) //对指定元素的数组进行匹配 输出:Hello,Mike
match1(arr3) //对指定个数元素的数组进行匹配 输出 hello,Jim,Mike,Lucy
match1(arr4) //未知数组匹配 输出:hi,what's your name
5.case class与模式匹配
Scala中可以使用case class声明样例类,并根据输入的样例类的类型来进行匹配
//定义一个case class
class Person
case class Teachers(name:String) extends Person
case class Student(name:String) extends Person
case class Worker(name:String,work:String) extends Person
case class Stranger() extends Person
object test {
def main(args: Array[String]): Unit = {
def matchclass(p:Person)=p match {
case Teachers(name) => println("my name is" + name + ".I'm a teacher")
case Student(name) => println("my name is" + name + ".I'm a student")
case Worker(name, work) if work == "repairman" => println("my name is" + name + ".I'm a repairman") //同种类型使用if守卫需要放在前面
case Worker(name, work) => println("my name is" + name + ".I'm a worker")
case _ => println("hei,who are you?")
}
val p1=Teachers("张三")
val p2=Student("李四")
val p3=Worker("王五","repairman")
val p4=Worker("赵六","煤矿工")
matchclass(p1)
matchclass(p2)
matchclass(p3)
matchclass(p4)
}
}
6.Option与模式匹配
Scala有一种特殊的类型,叫做Option。
Option有两种值,一种是Some,表示有值,一种是None,表示没有值。
Option通常会用于模式匹配中,用于判断某个变量是有值还是没有值,这比null来的更加简洁明了
Spark源码中大量地使用了Option,比如Some(a)、None这类语法.
val map=Map("Leo"->"A","Jack"->"B","Lucy"->"C")
def match1(name:String)={
val score=map.get(name)
score match {
case Some(grade)=> println(name+" get a "+grade)
case None=> println("Sorry,"+name+" no grade")
}
}
match1("Jac") //输出 Sorry,Jac no grade
match1("Jack") //输出Jack get a B