在Scala中Extractor为定义了unapply方法的对象。unapply的作用是匹配一个值,然后从中提取所需的部分。通常unapply和apply一起定义,但这不是必须的。例如,前面定义上篇文章中所需的Email对象。
- object EMail {
- def apply(user:String,domain:String) = user + "@" + domain
- def unapply(str:String) :Option[(String,String)] ={
- val parts = str split "@"
- if(parts.length==2) Some(parts(0),parts(1)) else None
- }
- }
Email对象定义了apply和unapply方法,apply方法没有什么特别之处,而unapply方法则把EMail对象变成了一个Extractor。在某种程度上来说,unapply和apply的作用相反,apply方法把两个字符串参数变成一个Email地址,而unapply方法反向变换,把一个字符串分解成两个部分:用户名和域名。unapply方法必须处理不能把一个字符串分解成两部分的情况,这也是为什么这里unapply方法返回Option类型的原因。
简单的测试如下:
- scala> EMail.unapply("james@guidebee.com")
- res1: Option[(String, String)] = Some((james,guidebee.com))
- scala> EMail.unapply("James Shen")
- res2: Option[(String, String)] = None
现在,模式匹配碰到一个模式引用到一个Exactor对象时,会调用该对象的unapply方法,比如
- selectorString match { case EMail(user,domain) => ...
会调用
- EMail.unapply(selectorString)
例如:
- "james.shen@guidebee.com" match{
- case EMail(user,domain) => println (user +" AT " + domain)
- case _ =>
- }
- james.shen AT guidebee.com