Scala 速通語法(十二)| 模式匹配
阿新 • • 發佈:2021-11-08
match 模式匹配
基本介紹
- Scala 中的模式匹配類似於 Java 中的 switch 語法,但是更加強大
- 模式匹配語法中,採用 match 關鍵字宣告,每個分支採用 case 關鍵字進行宣告,當需要匹配時,會從第一個 case 分支開始,如果匹配成功,那麼執行對應的邏輯程式碼,如果匹配不成功,繼續執行下一個分支進行判斷。如果所有 case 都不匹配,那麼會執行 case _ 分支,類似於 Java 中 default 語句
val oper = '-' val n1 = 20 val n2 = 10 var res = 0 //說明 //1. match (類似 java switch) 和case 是關鍵字 //2. 如果匹配成功, 則 執行 => 後面的程式碼塊. //3. 匹配的順序是從上到下,匹配到一個就執行對應的 程式碼 //4. => 後面的程式碼塊 不要寫 break ,會自動的退出 match //5. 如果一個都沒有匹配到,則執行 case _ 後面的程式碼塊 oper match { case '+' => res = n1 + n2 case '-' => res = n1 - n2 case '*' => res = n1 * n2 case '/' => res = n1 / n2 case _ => println("oper error") } println("res=" + res)
守衛
- 如果想要表達匹配某個範圍的資料,就需要在模式匹配中增加條件守衛
// 說明..
// 如果 case 後有 條件守衛即 if ,那麼這時的 _ 不是表示預設匹配
// 表示忽略 傳入 的 ch
case _ if ch.toString.equals("3") => digit = 3
case _ if (ch > 1110 || ch < 120) => println("ch > 10")
模式中的變數
- 如果在 case 關鍵字後跟變數名,那麼 match 前表示式的值會賦給那個變數
ch match { case '+' => println("ok~") // 下面 case mychar 含義是 mychar = ch case mychar => println("ok~" + mychar) case _ => println ("ok~~") }
型別匹配
- 可以匹配物件的任意型別,這樣做避免了使用 isInstanceOf 和 asInstanceOf 方法
val result = obj match {
case a: Int => a
case b: Map[String, Int] => "物件是一個字串-數字的 Map 集合"
case c: Map[Int, String] => "物件是一個數字-字串的 Map 集合"
}
型別匹配注意事項
- Map[String, Int] 和 Map[Int, String]是兩種不同的型別,其它類推
- 在進行型別匹配時,編譯器會預先檢測是否有可能的匹配,如果沒有則報錯
val result = obj match {
case i : Int => i
}
//case i : Int => i 表示 將 i = obj (其它類推),然後再判斷型別
- 如果 case _ 出現在 match 中間,則表示隱藏變數名,即不使用,而不是表示預設匹配
- unapply 方法是物件提取器
for迴圈模式匹配
for ((k, v) <- map if v >= 1) {
println(k + " ---> " + v)
}
樣例(模板)類
-
- 樣例類仍然是類
-
- 樣例類用 case 關鍵字進行宣告。
-
- 樣例類是為模式匹配而優化的類
-
- 構造器中的每一個引數都成為 val——除非它被顯式地宣告為 var(不建議這樣做)
-
- 在樣例類對應的伴生物件中提供 apply 方法讓你不用 new 關鍵字就能構造出相應的物件
-
- 提供 unapply 方法讓模式匹配可以工作
-
- 將自動生成 toString、equals、hashCode 和 copy 方法(有點類似模板類,直接生成)
-
- 除上述外,樣例類和其他類完全一樣。你可以新增方法和欄位,擴充套件它們
abstract class Amount
case class Dollar(value: Double) extends Amount //樣例類
case class Currency(value: Double, unit: String) extends Amount //樣例類
case object NoAmount extends Amount //樣例類
case 語句的中置(綴)表示式
List(1, 3, 5, 9) match { //測試
//1.兩個元素間::叫中置表示式,至少 first,second 兩個匹配才行.可以多 但最後一個匹配剩餘的
//2.first 匹配第一個 second 匹配第二個,third匹配第三個 rest 匹配剩餘部分(5,9)
case first :: second :: third :: rest => println(first + " " + second + " " + " " + third + rest.length + " " + rest) //
case _ => println("匹配不到...")
}
//結果: 1 3 5 1 List(9)
密封類
- 如果讓case類的所有子類都必須宣告在該類的相通原始檔中定義 可以將樣例類的通用超類宣告為
sealed
,這個超類稱之為密封類 - 密封類不能再其他檔案中定義子類