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

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

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

對于一個只綁定一個變量的情況有些特殊。Scala 沒有所謂“一元組”,為返回一個變量,該變量直接封裝在 Some 中返回。下面的例子的 Twice 匹配一個含有兩個連續(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
    }
}

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

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

這個例子只定義了 unapply 方法,因為這里定義 apply 方法無任何意義。

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

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

第一個模式定義去匹配所有的 Email 地址,這個 Email 地址的用戶名為大寫,并且有兩個相同的字符串構(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

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