Scala 導覽

萃取器物件

語言

萃取器物件是一個具有 unapply 方法的物件。而 apply 方法就像一個建構函式,它接收引數並建立一個物件,unapply 則接收一個物件並嘗試回傳引數。這最常在模式配對和部分函式中使用。

import scala.util.Random

object CustomerID {

  def apply(name: String) = s"$name--${Random.nextLong()}"

  def unapply(customerID: String): Option[String] = {
    val stringArray: Array[String] = customerID.split("--")
    if (stringArray.tail.nonEmpty) Some(stringArray.head) else None
  }
}

val customer1ID = CustomerID("Sukyoung")  // Sukyoung--23098234908
customer1ID match {
  case CustomerID(name) => println(name)  // prints Sukyoung
  case _ => println("Could not extract a CustomerID")
}
import scala.util.Random

object CustomerID:

  def apply(name: String) = s"$name--${Random.nextLong()}"

  def unapply(customerID: String): Option[String] =
    val stringArray: Array[String] = customerID.split("--")
    if stringArray.tail.nonEmpty then Some(stringArray.head) else None

val customer1ID = CustomerID("Sukyoung")  // Sukyoung--23098234908
customer1ID match
  case CustomerID(name) => println(name)  // prints Sukyoung
  case _ => println("Could not extract a CustomerID")

apply 方法從 name 建立一個 CustomerID 字串。unapply 執行相反的動作以取得 name。當我們呼叫 CustomerID("Sukyoung") 時,這是呼叫 CustomerID.apply("Sukyoung") 的簡寫語法。當我們呼叫 case CustomerID(name) => println(name) 時,我們使用 CustomerID.unapply(customer1ID) 呼叫 unapply 方法。

由於值定義可以使用樣式來引入新變數,因此可以使用萃取器來初始化變數,其中 unapply 方法提供值。

val customer2ID = CustomerID("Nico")
val CustomerID(name) = customer2ID
println(name)  // prints Nico

這等於 val name = CustomerID.unapply(customer2ID).get

val CustomerID(name2) = "--asdfasdfasdf"

如果沒有匹配,則會擲回 scala.MatchError

val CustomerID(name3) = "-asdfasdfasdf"

unapply 的回傳類型應如下選擇

  • 如果它只是一個測試,則回傳 Boolean。例如 case even()
  • 如果它回傳 T 型別的單一子值,則回傳 Option[T]
  • 如果您想要回傳多個子值 T1,...,Tn,請將它們分組在一個選用 tuple Option[(T1,...,Tn)] 中。

有時,要萃取的值的數量並非固定,我們希望根據輸入回傳任意數量的值。對於此使用案例,您可以使用具有 unapplySeq 方法的萃取器,該方法會回傳 Option[Seq[T]]。這些樣式的常見範例包括使用 case List(x, y, z) => 解構 List,以及使用正規表示法 Regex 分解 String,例如 case r(name, remainingFields @ _*) =>

此頁面的貢獻者