2013-05-04 229 views
7

爲什麼不可能鏈接模式匹配結構?例如,下面是合法的,如果無厘頭,模式匹配「返回」值

val a = ADT(5) 

val b = a match { 
    case ADT(a) if a > 4 => ADT(a * 3) 
    case ADT(a) => ADT(a + 1) 
} 
b match { 
    case ADT(a) if a > 13 => doSomething(a) 
    case _ => {} 
} 

但下面的不是:

a match { 
    case ADT(a) if a > 4 => ADT(a * 3) 
    case ADT(a) => ADT(a + 1) 
} match { 
    case ADT(a) if a > 13 => doSomething(a) 
    case _ => {} 
} 

我懷疑這是因爲我不應該擺在首位那樣做,但原則我不明白爲什麼它不合法。

+4

'(匹配{..})匹配{..}'會工作。 – user2246674 2013-05-04 04:55:50

回答

5

是的,它應該工作,因爲(幾乎)在Scala中的所有內容都是表達式,並且每個表達式都可以用作模式匹配。

在這種情況下,模式匹配是一個表達式,所以它可以被另一個「鏈接」模式匹配使用。但編譯器不喜歡它。

給編譯器括號中的小提示可以幫助:

case class ADT(value: Int) 

val a = ADT(5) 

(a match { 
    case ADT(a) if a > 4 => ADT(a * 3) 
    case ADT(a) => ADT(a + 1) 
}) match { 
    case ADT(a) if a > 13 => println(a) 
    case _ => {} 
} 
+0

我偶然發現了圓括號的解決方法,但我不明白爲什麼它在這裏是必要的,但沒有必要用'val a = if(false)6 else if(true)if(true)5 else 3 else 2' – 2013-05-04 05:11:22

+0

@CarlSummers編譯器只能推斷這麼多。這只是操作的順序。如有疑問(您或編譯器)明確。 (我實際上對Scala很陌生,但這是我喜歡的東西之一。) – hangtwenty 2013-08-13 12:11:44

3

你的直覺是正確的;這不是廢話—通常你能夠鏈接中綴運營商在這種方式,沒有括號(如其他用戶已建議)。實際上,match曾經作爲—的方法實現,並且作爲中綴運算符(默認情況下爲左關聯)—工作,因此您的備用語法可以工作。但是,在Scala 2.5中,match被作爲一種特殊的語言結構而不是一種方法。不幸的是,我不知道爲什麼這樣做,但這是原因:match而不是一箇中綴操作符,儘管看起來如此。