一个提取器对象会有一个unapply
方法。apply
方法类似于接受参数并创建对象的构造器,反过来unapply
则是接受一个对象并试图返回原来的参数。这一点在模式匹配和偏函数中经常使用。
1 | import scala.util.Random |
apply
方法由一个name
创建了一个CustomerID
字符串。unapply
则反过来获得了name
。当我们调用CustomerID("Sukyoung")
时,其实是CustomerID.apply("Sukyoung")
的一种简写形式。而当我们调用case CustomerID(name) => println(name)
时,则实际调用的是unapply
方法。
另外unapply
方法也可以用来分配一个值。
1 | val customer2ID = CustomerID("Nico") |
这个其实和val name = CustomerID.unapply(customer2ID).get
是等价的。
1 | val CustomerID(name2) = "--asdfasdfasdf" |
如果没有匹配上,则抛出一个scala.MatchError
:
1 | val CustomerID(name3) = "-asdfasdfasdf" |
关于unapply
的返回类型有以下几种选择:
- 如果仅仅是一个判断,则返回一个
Boolean
。例如case even()
。 - 如果要返回
T
类型的单个子值,则返回一个Option[T]
。 - 如果要返回多个子值如
T1,...,Tn
,则可以把它们组合起来放在一个可选的元组Option[(T1,...,Tn)]
当中。
有时候子值的数量不固定,我们则可以返回一个序列。因此这时候,你就可以通过定义unapplySeq
的方式来返回一个Option[Seq[T]]
,这种用法常见于case List(x1, ..., xn)
模式中。