2011-12-23 66 views
3

我再次與Scala的語法混淆。我希望這只是工作的優良:斯卡拉的匹配表達與否?

// VERSION 1 
def isInteractionKnown(service: Service, serviceId: String) = service match { 
    case TwitterService => 
     twitterInteractions.findUuidByTweetId(serviceId.toLong) 
    case FacebookService => 
     facebookInteractions.findUuidByServiceId(serviceId) 
}.isDefined 

:兩個findUuidByTweetIdfindUuidByServiceId返回Option[UUID]

scalac告訴我:

error: ';' expected but '.' found. 
}.isDefined 

當我讓我的IDE(IDEA)格式化該代碼,.isDefined部分結束了它自己的一行。這就好像match不是一個表達式。但在我看來,我所做的功能上等同於:

// VERSION 2 
def isInteractionKnown(service: Service, serviceId: String) = { 
    val a = service match { 
     case TwitterService => 
      twitterInteractions.findUuidByTweetId(serviceId.toLong) 
     case FacebookService => 
      facebookInteractions.findUuidByServiceId(serviceId) 
    } 

    a.isDefined 
} 

它解析並完全按照我的要求。爲什麼第一個語法不被接受?

回答

10

是的,這是一個表達式。不過,並非所有的表達方式都是相同根據Scala Language Specification第6章「表達式」,方法調用的接收者只能來自所有表達式(文法中的SimpleExpr)的(語法)子集,並且match表達式不在該子集中(既不是if表達式, 例如)。

因此,你需要把他們周圍的括號:

(service match { 
    case => ... 
    ... 
}).isDefined 

This question有一些更多的答案。

(編輯合併一些意見。)

+1

但是爲什麼?如果匹配是一個表達式,爲什麼我需要將它轉換爲另一個表達式? – 2011-12-23 15:45:19

+0

因爲它不是一個簡單的表達式。看到[這個問題](http://stackoverflow.com/questions/7529668/scala-can-you-use-foo-match-bar-in-an-expression-without-parentheses)瞭解更多。 – agilesteel 2011-12-23 16:09:28

+2

'foo bar {baz} .quux'明顯解析爲'foo bar({baz} .quux)',而不是'(foo bar {baz}).quux' – 2011-12-23 17:14:49