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,将它们分组到可选元组 Option[(T1,...,Tn)] 中。

有时,要提取的值的数量不是固定的,我们希望根据输入返回任意数量的值。对于此用例,您可以使用 unapplySeq 方法定义提取器,该方法返回 Option[Seq[T]]。这些模式的常见示例包括使用 case List(x, y, z) => 解构 List,以及使用正则表达式 Regex 分解 String,例如 case r(name, remainingFields @ _*) =>

此页面的贡献者