Scala 专题教程-Extractors(2):定义 Extractor

jerry Scala 2015年11月25日 收藏

在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