Scala提供了一个强大的匹配功能---模式匹配,类似于Java的switch case语法,即对一个值进行判断,针对不同的条件,做出不同的判断。
Scala的模式匹配比Java的Switch case功能强大的多。后者只能对值进行判断,但是前者除了可以对值判断以外,还可以对类型进行匹配,对Array、List的元素情况进行匹配,对样例类(case class)进行匹配,甚至还可以对无值有值(option)进行匹配。
match case的基本语法如下:变量 match {case 值 => 代码}。如果值为下划线,表示不满足以上任意条件下的情况。并且,match case中只要有一个case分支满足并处理了,就不会进行下一个分支的判断。
- 模式匹配基本语法
//match case最基本用法:对变量值进行模式匹配 def gradeEvaluate(grade: String, name: String):String = { val evaluations: String = grade match { case "A" => "Excellent" case "B" => "Good" case "C" => "Just so so" case _ => "You need work hard" } evaluations } //模式匹配中使用守卫if //在case后的条件判断中,不仅仅只是提供一个值,而且可以在值后边再加一个if守卫,进行双重过滤 def studentScore(name:String,score:String): Unit ={ score match { case "A"=>println("excellent") case "B"=>println("good") case "C"=>println("soso") case _ if name=="ming"=>print(name+",you are good boy,come on!")//if守卫 case _ =>println("you need work harder") } } //Scala的模式匹配还有一个特点:将模式匹配的默认情况_,替换为一个变量名,此时模式匹配就会将要匹配的值赋予给这个变量,从而可以在后面的处理语句中使用变量。 //对于下划线_这种情况,所有不满足前边的case的值,都会进入这种默认情况进行处理,如果,我们需要拿到具体的值进行处理,就需要使用这种在模式匹配中使用变量赋值的语法 def studentScore(name:String,score:String): Unit ={ score match { case "A"=>println("excellent") case "B"=>println("good") case "C"=>println("soso") case _ if name=="ming"=>print(name+",you are good boy,come on!") case score =>println("you need work harder,your score only " + score) //变量赋值 } }
- 对Array和List进行匹配
//对Array数组进行模式匹配,分别可以匹配带有指定元素的数组、带有指定个数元素的数组、以某元素开头的数组 //对List进行模式匹配,与Array类似,但是需要使用List特有的::操作符 def greeting(arr: Array[String]) { arr match { case Array("Leo") => println("Hi, Leo!") //匹配一个元素 case Array(girl1, girl2, girl3) => println("Hi, girls, nice to meet you. " + girl1 + " and " + girl2 + " and " + girl3) //匹配三个元素 case Array("Leo", _*) => println("Hi, Leo, please introduce your friends to me.") //匹配以Leo开头,三个元素会被上面匹配scala匹配机制是匹配到就停止 case _ => println("hey, who are you?") } } //List def greeting(list: List[String]) { list match { case "Leo" :: Nil => println("Hi, Leo!")//匹配一个元素 case girl1 :: girl2 :: girl3 :: Nil => println("Hi, girls, nice to meet you. " + girl1 + " and " + girl2 + " and " + girl3)//匹配三个元素 case "Leo" :: tail => println("Hi, Leo, please introduce your friends to me.")//匹配以Leo开头 case _ => println("hey, who are you?") } }
- 对类型进行匹配
//Scala模式匹配的强大之处就在于,可以直接进行匹配类型。 //进行类型模式匹配的时候,就要使用下面格式:case 变量:类型 => 代码 //异常处理 def processException(e: Exception) { e match { case e1: IllegalArgumentException => println("you have illegal arguments! exception is: " + e1) case e2: FileNotFoundException => println("cannot find the file you need read or write!, exception is: " + e2) case e3: IOException => println("you got an error while you were doing IO operation! exception is: " + e3) case _: Exception => println("cannot know which exception you have!" ) } }
- case class 模式匹配
//Scala提供了一种特殊的类,用case class进行声明,也称为样例类。有点类似于Java的JavaBean,即只定义field,并且又Scala编译时自动提供getter和setter方法,但是没有method。 //case class的主构造函数接受的参数并不需要使用var或者val修饰,Scala会自动使用val修饰(但是如果自己使用var修饰,还是会按照var来) //Scala自动为case class定义了伴生对象,也就是object,并且定义了apply()方法,该方法接受主构造函数中相同的参数,并返回case class对象。 //校园门禁 class Person case class Teacher(name:String,subject:String) extends Person case class Student(name:String,classroom:Int) 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 entranceGuard(p:Person): Unit ={ p match { case Student(name,classroom)=>println(s"hello,$name,welcome to school,your classroom is $classroom") case Teacher(name,subject)=>println(s"hello,$name,welcome to school,your teach $subject") case Worker(name,work) if work=="repairman"=>println(s"hello,$name,you should leave school afternoon") case Worker(name,work)=>println(s"hello,$name,you should leave school 2 hours later") case _=>println(s"stranger,you can not into school") } } entranceGuard(Worker("Jason","cleaner")) } }
- Option与模式匹配
//Scala有一种特殊的类型Option,Option有两种值:Some:表示有值;None:表示无值 //Option通常会用于模式匹配,判断某个变量有值还是没有值,这比null来的简洁明了 //Option的用法必须掌握,重重重 val grades = Map("Leo" -> "A", "Jack" -> "B", "Jen" -> "C") def getGrade(name: String) { val grade = grades.get(name) grade match { case Some(grade) => println("your grade is " + grade) case None => println("Sorry, your grade information is not in the system") } }