前面我們介紹了使用模式匹配來分解數(shù)據,本專題教程對這些概念加以推廣。到目前為止,構造器模式是和 Case Class 關聯(lián)在一起的。有些時候你希望使用類似的模式而不需要創(chuàng)建 Case Class。實際上你可能希望創(chuàng)建自定義的模式。 Extractor(解析器)可以幫助你完成這些任務。本篇以一個簡單的例子來介紹 Extractor 的概念和用法。
比方說給定一個代碼 Email 地址的字符串,你需要判斷它是否是一個有效的 Email 地址,如果是有效的 Email 地址,你需要分別取出用戶名和域名兩個部分。傳統(tǒng)的實現(xiàn)方法可以定義如下三個輔助函數(shù):
def isEmail(s:String): Boolean
def domain(s:String): String
def user(s:String): String
使用這些方法,你可以使用如下代碼分析輸入的字符串:
if(isEmail(s)) println(user(s) + " AT " + domain(s))
else println("not an email address")
這段代碼功能是正確的,但比較笨拙,而且如果需要同時有多個測試時情況就變得比較復雜,比如你在一串字符串中尋找相連的同一個用戶名的 Email 地址。
我們之前介紹的模式匹配處理這類問題非常有效。簡單你可以使用
Email(user,domain)
來匹配一個字符串。這個模式可以匹配含有“@”有個字符串,使用這個模式,你可以使用 user,domain 分別綁定用戶名和域名。我們使用模式匹配重寫前面的例子:
s match{
case Email(user,domain) => println (user + " AT " + domain)
case _ => println ("not an email address")
}
而解決尋找相連兩個同名的 Email 地址可以使用如下代碼:
s match{
case Email(u1,d1)::Email(u2:d2):: _ if(u1==u2) => ...
...
}
這段代碼看起來簡單明了,但問題是 String(s 的類型)不是一個 case class。 它們不具有可以表示為 Email(user,domain)的方法。 此時我們就可以借助于 Extractor,它們支持為這些內置的類型定義新的模式。