Scala Learn 5 模式匹配和樣例類 (待補充)

blair發表於2019-02-16

Chap 14 模式匹配和樣例類

focus on

  1. match 表示式 是一個更好的 switch

  2. 沒有模式匹配, 會丟擲 MatchError。 可以用 case _模式來避免

  3. 模式可以包含隨意定義的條件,稱做 守衛

  4. 你可以對錶達式的型別進行匹配; 優先選擇模式匹配而不是 isInstanceOf / asInstanceOf

  5. 你可以匹配陣列、元組 和 樣例類 的模式,然後將匹配到的不同部分繫結到變數

  6. 在 for 表示式中, 不能匹配的情況 會被安靜的跳過

  7. 樣式類,是編譯器會為之 自動產出 模式匹配 所需要的方法的類

  8. 樣例類 繼承層級中 的 公共超類 應該是 sealed 的

  9. 用 Option 來存放對於 maybe exist or not 的 value。 這比 null 更安全

package com.x.p14match

import java.lang.Character

/**
  * Date : 2016-04-12
  */
object Matchtest {

  def main(args: Array[String]) {

    /** 14.1 best switch  **/

    var sign = -20
    var ch: Char = `-`

    sign = ch match {
      case `+` => 1
      case `-` => -1
      case _ => 0
    }
    println("sign : " + sign)

    // scala 模式匹配 與 switch 是不同的
    // you can use anytype in match. not only number

    /** 14.2  守衛  **/

    ch = `8`
    var digit = 0

    ch match {
      case `+` => 1
      case `-` => -1
      case _ if Character.isDigit(ch) => digit = Character.digit(ch, 10) // 0 ~ 9

      case _ => sign = 2
    }
    println("sign : " + sign)
    println("digit : " + digit)

    /** 14.3  模式中的變數  **/

    // match中 變數 必須以小寫字母開頭, 否則 需要 `varname`

    /** 14.4 型別模式 **/

    var obj: Any = "123"

    var mk = obj match {
      case x: Int => x
      case s: String => Integer.parseInt(s)
      case _: BigInt => Int.MaxValue
      case _ => 0
    }

    println("type_k : " + mk)

    /** 14.5 匹配資料, 列表, 元組 **/

    // array

    val numArr = new Array[Int](5)
    numArr(0) = 1

    for (i <- 0 until numArr.length)
      println(i + ": " + numArr(i))

    val na_res = numArr match {
      case Array(0) => "0"            // inclue 0 array, only one elem, is 0
      case Array(x, y) => x + " " + y // only have 2 element array
      case Array(0, _*) => "0 ..."    // any by 0 begin array
      case _ => "something else"
    }

    println("na_res : " + na_res)

    // list

    val lst = List(0, 8, 9)

    val lstRes = lst match {
      case 0 :: Nil => "0"
      case x :: y :: Nil => x + " and " + y
      case 0 :: tail => "0 ..."
      case _ => "something else"
    }

    println("lstRes : " + lstRes)

    // tuple

    val pair = (2, 3.14, "Hello")

    val pairRes = pair match {
      case (0, _, _) => "0 ..."
      case (y, z, x) => z + 5
      case _ => "neither is 0"
    }

    println("pairRes : " + pairRes)

    /** 14.6 提取器 **/

    /** 14.7 變數宣告中的模式 **/

    val (x, y) = (1, 2)
    println(x + y)
    val (q, r) = BigInt(10) /% 3

    val Array(first, second, _*) = numArr


    println("first : " + first)


    /** 14.8 for 表示式中的模式 **/

    import scala.collection.JavaConversions.propertiesAsScalaMap // 將 Java 的 Properties 轉換成 Scala 對映
    for ((k, v) <- System.getProperties() if v == "")
      println("key : " + k)

    /** 14.9 樣例類 **/


  }
}

相關文章