鍍金池/ 教程/ Scala/ 無參數(shù)和帶一個(gè)參數(shù)的模式定義
定義 Extractor
正規(guī)表達(dá)式
Extractors 和 Seq 模式
可變參數(shù)的 Extractors
無參數(shù)和帶一個(gè)參數(shù)的模式定義
分解 Email 地址的例子

無參數(shù)和帶一個(gè)參數(shù)的模式定義

前面例子中的 unapply 方法在匹配成功時(shí)返回一個(gè)二元組。這可以很容易的推廣到多于兩個(gè)變量的情況。為了綁定N個(gè)變量,unapply 方法可以返回一個(gè) N 元祖,封裝在 Some 中。

對(duì)于一個(gè)只綁定一個(gè)變量的情況有些特殊。Scala 沒有所謂“一元組”,為返回一個(gè)變量,該變量直接封裝在 Some 中返回。下面的例子的 Twice 匹配一個(gè)含有兩個(gè)連續(xù)的相同字符串的情況。

object Twice {
    def apply(s:String) = s + s
    def unapply(s:String):Option[String] ={
        val length=s.length/2
        val half = s.substring(0,length)
        if(half == s.substring(length)) Some(half) else None
    }
}

一個(gè) Extractor 也可以綁定任何變量,這種情況下可以返回 true 和 false 代表匹配成功與否。比如下面的例子匹配一個(gè)字符串是否都是大寫字母:

object UpperCase {
    def unapply(s:String):Boolean = s.toUpperCase ==s 
}

這個(gè)例子只定義了 unapply 方法,因?yàn)檫@里定義 apply 方法無任何意義。

之后我們可以利用上面定義的 Twice 和 UpperCase Extractor 組合構(gòu)造組合的模式定義(還記得之前提到的 Monoid,設(shè)計(jì)模式 Option 類型就是一個(gè) Monoid,Monoid 一個(gè)特點(diǎn)就是可以任意組合)。

def userTwiceUpper(s:String) = s match{
    case EMail(Twice(x @ UpperCase()),domain) =>
        "match:" + x + " in domain " + domain
    case _ => "no match"
}

第一個(gè)模式定義去匹配所有的 Email 地址,這個(gè) Email 地址的用戶名為大寫,并且有兩個(gè)相同的字符串構(gòu)成。例如:

scala> userTwiceUpper("DIDI@hotmail.com")
res1: String = match:DI in domain hotmail.com
scala> userTwiceUpper("DIDO@hotmail.com")
res2: String = no match
scala> userTwiceUpper("didi@hotmail.com")
res3: String = no match

在這個(gè)模式定義中,UpperCase 后面跟了一個(gè)空括號(hào),這個(gè)空括號(hào)是必須的,否則模式變成匹配和 UpperCase 相等。即使 UpperCase 沒有綁定任何變量,但你可以利用前面 Scala 專題教程 -Case Class 和模式匹配(5): 模式的種類(四)的方法為這個(gè)模式定義綁定一個(gè)自定義的變量。這是使用“@”來定義的。本例為x。