2014-01-29 46 views
1

我有一個昂貴的case語句,它需要命中數據庫以確定一個完整匹配。如果有匹配,從上述調用的結果必須被用來進行進一步的操作:從Scala模式匹配中的昂貴語句別名對象

def intent = { 
    case request @ GET(Path(Seg(database :: Nil))) if recordsFrom(database) != Nil => 
     renderOutput(recordsFrom(database)) 
    case ... 
} 

我想打電話給recordsFrom(database)只有一次。在上面的例子中,它被調用兩次。似乎我應該可以在陳述中應用一些別名?

回答

2

出了什麼問題:

def intent = { 
    case request @ GET(Path(Seg(database :: Nil))) => 
    val records = recordsFrom(database) 
    if(!records.isEmpty){ 
     renderOutput(records) 
    } else { 
     ... 
    } 
    case ... 

你可以,如果你想避免過多的嵌套塊第一種情況下的身體移動到不同的功能。

+0

當數據庫不包含記錄時,這將導致匹配。對於這個人爲的例子來說也許很好,但是對於產生的部分函數會產生非常不同的行爲。 –

+0

那又如何?您可以根據您的請求進行匹配,使用數據庫檢索記錄列表,然後測試以查看列表是否爲空,您可以在if語句中處理這兩種情況。模式匹配很酷,但它不是每個問題的答案。 – vptheron

3

Lawrence,從我看到你正在使用Unfiltered來處理RESTful請求,但是你還將數據庫查找與該響應篩選結合起來。我會建議你不要這樣做。相反,我會安排你的事情如下:

val dbReqCommand = new DBRequestCommand(myDbConPool) 

def intent ={ 
    case req @ GET(Path(Seq(database :: Nil))) => dbReqCommand(req, database) 
} 

其中你封裝在一個對象數據庫的請求,你可以替補上場用於測試目的(認爲沒有DB後端集成測試。)在請求處理程序中然後可能放在響應:

Option(recordsFrom(database)) match{ 
    case Some(value) => OK ~> renderOpupt(value) 
    case None => //an error response or Pass 
} 

這樣,你可能會沿着線的東西:

trait DBReqPlan{ 
    def dbReqCommand: RequestCommand[String] 

    def intent ={ 
    case req @ GET(Path(Seq(database :: Nil))) => dbReqCommand(req, database) 
    } 
} 

這是更容易測試反對和W ork與。

+0

感謝未經過濾的建議:)從這些答案看來,Scala並未提供在模式匹配情況下將別名應用於昂貴對象創建的機制。我猜這就是未過濾引入Pass的確切原因(即,在調用更高級的邏輯之後放棄匹配)...似乎是一個通用的要求... –

+1

@LawrenceWagerfield那麼,這並不完全正確。你可以用自己的'unapply'來創建你自己的物品,然後你就可以匹配。我在Unfiltered之前完成了它,我稱之爲「路線」。然後你可以訪問許多東西。也就是說,將DB訪問作爲路由的一部分,這仍然是一種相當糟糕的做法。身份驗證可以在響應對象內處理,而不是。 – wheaties

+0

一個絕妙的主意(用於其他用例)! –