1. 程式人生 > 其它 >Scala 速通語法(十二)| 模式匹配

Scala 速通語法(十二)| 模式匹配

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)
}

樣例(模板)類

    1. 樣例類仍然是類
    1. 樣例類用 case 關鍵字進行宣告。
    1. 樣例類是為模式匹配而優化的類
    1. 構造器中的每一個引數都成為 val——除非它被顯式地宣告為 var(不建議這樣做)
    1. 在樣例類對應的伴生物件中提供 apply 方法讓你不用 new 關鍵字就能構造出相應的物件
    1. 提供 unapply 方法讓模式匹配可以工作
    1. 將自動生成 toString、equals、hashCode 和 copy 方法(有點類似模板類,直接生成)
    1. 除上述外,樣例類和其他類完全一樣。你可以新增方法和欄位,擴充套件它們

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,這個超類稱之為密封類
  • 密封類不能再其他檔案中定義子類