Scala有一個十分強大的模式匹配機制,可以應用到很多場合:如switch語句、類型檢查等。並且Scala還提供了樣例類,對模式匹配進行了優化,可以快速進行匹配。
1、字符匹配
def main(args: Array[String]): Unit = { val charStr = '6' charStr match { case '+' => println("匹配上了加號") case '-' => println("匹配上了減號") case '*' => println("匹配上了乘號") case '/' => println("匹配上了除號") //注意。所有的模式匹配都必須最終匹配上一個值,如果沒有匹配上任何值,就會報錯 // case _ => println("都沒有匹配上,我是默認值") } } |
2、 匹配字符串
def main(args: Array[String]): Unit = { val arr = Array("hadoop", "zookeeper", "spark") val name = arr(Random.nextInt(arr.length)) name match { case "hadoop" => println("大數據分布式存儲和計算框架...") case "zookeeper" => println("大數據分布式協調服務框架...") case "spark" => println("大數據分布式內存計算框架...") case _ => println("我不認識你...") }
} |
3、守衛
模式匹配當中,我們也可以通過條件進行判斷
def main(args: Array[String]): Unit = { var ch = "500" var sign = 0 ch match { case "+" => sign = 1 case "-" => sign = 2 case _ if ch.equals("500") => sign = 3 case _ => sign = 4 } println(ch + " " + sign) } |
4、 匹配類型
def main(args: Array[String]): Unit = { //注意泛型擦除,在模式匹配當中的類型匹配中,除了Array類型以為,所有的其他的數據類型都會被擦除掉 val a = 3 val obj = if(a == 1) 1 else if(a == 2) "2" else if(a == 3) BigInt(3) else if(a == 4) Map("aa" -> 1) else if(a == 5) Map(1 -> "aa") else if(a == 6) Array(1, 2, 3) else if(a == 7) Array("aa", 1) else if(a == 8) Array("aa") val r1 = obj match { case x: Int => x case s: String => s.toInt case BigInt => -1 //不能這么匹配 case _: BigInt => Int.MaxValue case m: Map[String, Int] => "Map[String, Int]類型的Map集合" case m: Map[_, _] => "Map集合" case a: Array[Int] => "It's an Array[Int]" case a: Array[String] => "It's an Array[String]" case a: Array[_] => "It's an array of something other than Int" case _ => 0 } println(r1 + ", " + r1.getClass.getName) } |
5、匹配數組、元組、集合
def main(args: Array[String]): Unit = { val arr = Array(0, 3, 5) arr match { case Array(0, x, y) => println(x + " " + y) case Array(0) => println("only 0") //匹配數組以1 開始作為第一個元素 case Array(1, _*) => println("0 ...") case _ => println("something else") }
val lst = List(3, -1) lst match { case 0 :: Nil => println("only 0") case x :: y :: Nil => println(s"x: $x y: $y") case 0 :: tail => println("0 ...") case _ => println("something else") }
val tup = (1, 3, 7) tup match { case (1, x, y) => println(s"1, $x , $y") case (_, z, 5) => println(z) case _ => println("else") } } |
注意:在Scala中列表要么為空(Nil表示空列表)要么是一個head元素加上一個tail列表。
9 :: List(5, 2) :: 操作符是將給定的頭和尾創建一個新的列表
注意::: 操作符是右結合的,如9 :: 5 :: 2 :: Nil相當於 9 :: (5 :: (2 :: Nil))
6、 樣例類
樣例類首先是類,除此之外它是為模式匹配而優化的類,樣例類用case關鍵字進行聲明。樣例類主要是使用在我們后面的sparkSQL當中,通過樣例類來映射我們的表當中的對象
定義形式:
case class 類型,是多例的,后面要跟構造參數。 case class Student(name:String)
case object 類型,是單例的。 case object Person
case class SubmitTask(id: String, name: String) case class HeartBeat(time: Long) case object CheckTimeOutTask //1、樣例類當中的主構造器參數默認為val的 //2、樣例類當中的apply和unapply方法自動生成 object CaseDemo04 extends App { val arr = Array(CheckTimeOutTask, HeartBeat(12333), SubmitTask("0001", "task-0001")) arr(2) match { case SubmitTask(id, name) => { println(s"$id,$name") println(id) println(name) println(id+"\t"+name) } case HeartBeat(time) => { println(time) } case CheckTimeOutTask => { println("check") } } } |
7、偏函數
被包在花括號內沒有match的一組case語句是一個偏函數,它是PartialFunction[A, B]的一個實例,A代表輸入參數類型,B代表返回結果類型,常用作輸入模式匹配,偏函數最大的特點就是它只接受和處理其參數定義域的一個子集。
val func1: PartialFunction[String, Int] = { case "one" => 1 case "two" => 2 // case _ => -1 }
def func2(num: String) : Int = num match { case "one" => 1 case "two" => 2 case _ => -1 }
def main(args: Array[String]) { println(func1("one")) println(func2("one")) //如果偏函數當中沒有匹配上,那么就會報錯,我們可以通過isDefinedAt來進行判斷 // println(func1("three")) println(func1.isDefinedAt("three")) if(func1.isDefinedAt("three")){ println("hello world") }else{ println("world hello") } } |