一个对象使用一个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") }
apply 方法从一个 name字符串创建一个CustomerID 类。unapply 则是将 CustomerId 反向解析为name。当我们调用 CustomerId("Sukyoung") 时,实际上是 CusomerId.apply("Sukyoung")的一个简写语法。当我们调用 case CustomerId(name) => println(name) ,实际上调用的是 CustomerId.unapply(customer1Id)
由于值定义可以用模式匹配引入新变量,因此对象提取器也可以初始化一个变量,只需要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,请返回 optional 元组 Option[(T1,...,Tn)
有时,要提取的值的数量不是固定的,我们希望返回任意数量的值,具体取决于输入。对于此用例,可以使用unapplySeq
返回的方法定义提取器Option[Seq[T]]
。这些模式的常见例子包括解构List
使用case List(x, y, z) =>
和String
使用使用正则表达式Regex
(如case r(name, remainingFields @ _*) =>
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。