Scala模式匹配

  Scala提供了一个强大的匹配功能---模式匹配,类似于Java的switch case语法,即对一个值进行判断,针对不同的条件,做出不同的判断。

  Scala的模式匹配比Java的Switch case功能强大的多。后者只能对值进行判断,但是前者除了可以对值判断以外,还可以对类型进行匹配,对Array、List的元素情况进行匹配,对样例类(case class)进行匹配,甚至还可以对无值有值(option)进行匹配。

  

  match case的基本语法如下:变量 match {case 值 => 代码}。如果值为下划线,表示不满足以上任意条件下的情况。并且,match case中只要有一个case分支满足并处理了,就不会进行下一个分支的判断。

  1. 模式匹配基本语法
     
    //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)  //变量赋值
      }
    }
    
  2. 对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?")
      }
    }
    
  3. 对类型进行匹配
     
    //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!" )
      }
    }
    
  4. 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"))
      }
    }
    
  5. 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")
      }
    }
    
原文地址:https://www.cnblogs.com/zbw1112/p/12092129.html