Extractor Object是有unapply
方法的對象电湘。apply
方法像是構(gòu)造函數(shù),可以帶參數(shù)以及創(chuàng)建對象鹅经,unapply
方法根據(jù)對象嘗試返回其參數(shù)寂呛。常用于模式匹配和partial functions。
import scala.util.Random
object CustomerID {
def apply(name: String) = s"$name--${Random.nextLong}"
def unapply(customerID: String): Option[String] = {
val name = customerID.split("--").head
if (name.nonEmpty) Some(name) 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
方法根據(jù)name
創(chuàng)建了CustomerID
字符串瘾晃。unapply
逆向獲取name
參數(shù)贷痪。當(dāng)調(diào)用CustomerID("Sukyoung")
時(shí),相當(dāng)于調(diào)用CustomerID.apply("Sukyoung")
酗捌。當(dāng)調(diào)用case CustomerID(name) => customer1ID
時(shí)呢诬,相當(dāng)于調(diào)用unapply
方法涌哲。
unapply
方法也可用于賦值胖缤。
val customer2ID = CustomerID("Nico")
val CustomerID(name) = customer2ID
println(name) // prints Nico
等價(jià)于val name = CustomerID.unapply(customer2ID).get
尚镰。如果沒有匹配,會拋出scala.MatchError
:
val CustomerID(name2) = "--asdfasdfasdf"
unapply
的返回類型應(yīng)該按照如下方式選擇:
- 如果只是測試哪廓,返回Boolean狗唉。例如case even()。
- 如果返回類型T的一個(gè)sub-value涡真,則返回Option[T]分俯。
- 如果想要返回多個(gè)sub-value T1,...,Tn,使用元組組織Option[(T1,...,Tn)]哆料。
有時(shí)缸剪,sub-value的數(shù)量是固定的并且想要返回一個(gè)序列。為此东亦,也可以通過unapplySeq
定義模式杏节,返回Option[Seq[T]]。這個(gè)機(jī)制用于匹配模式case List(x1, ..., xn)
典阵。