2011-11-30 57 views
2

因此,我一直在閱讀關於在LiftWeb中使用Box的this article,這似乎是官方文檔的一部分,因爲它通過源代碼註釋鏈接在一起。 我的問題是爲什麼Box/Failure更喜歡實際編碼沒有null,並拋出一個Exception,它將被捕獲到頂級並轉換成適當的錯誤代碼/消息。因此,而不是爲什麼Box/Option在LiftWeb/Scala中不是Exception?

case "user" :: "info" :: _ XmlGet _ => 
    for { 
    id <- S.param("id") ?~ "id param missing" ~> 401 
    u <- User.find(id) ?~ "User not found" 
    } yield u.toXml 

爲什麼不

case "user" :: "info" :: _ XmlGet _ => User.find(S.param("id").openOrThrow(
    new IllegalArgumentException("idParamMissing"))).toXml 

,並有User.find扔東西一樣NotFoundException

+0

不錯的問題。我從來沒有想過... – drozzy

+0

@drozzy請確保你也閱讀郵件列表的答案:http://goo.gl/5Lv7V –

回答

2

想象一下,您有一種方法可以執行某些可能失敗的操作,例如獲取網頁。

def getUrl(url: String): NodeSeq = { 
    val page = // ... 
    // ... 
    if (failure) throw new PageNotFoundException() 
    page 
} 

如果你想使用它,你需要做的

val node = try { 
    getUrl(someUrl) 
} catch { 
    case PageNotFoundException => NodeSeq.Empty 
} 

或類似視情況而定。儘管如此,這看起來還可以。但是現在想象一下你想爲網址集合做到這一點。

val urls = Seq(url1, ...) 
val nodeseqs: Seq[NodeSeq] = try { 
    urls.map(getUrl) 
} catch { 
    case PageNotFoundException => Seq.Empty 
} 

好的,所以只要其中一個頁面無法加載,就返回一個空序列。如果我們想接收儘可能多的東西呢?

val urls = Seq(url1, ...) 
val nodeseqs: Seq[NodeSeq] = urls.map { url => 
    try { 
    getUrl(url) 
    } catch { 
    case PageNotFoundException => NodeSeq.Empty 
    } 
} 

現在我們的邏輯與錯誤處理代碼混合在一起。

比較這對以下幾點:

def getUrl(url: String): Box[NodeSeq] = { 
    val page = // ... 
    // ... 
    if (failure) Failure("Not found") 
    else Full(page) 
} 

val urls = Seq(url1, ...) 
val nodeseqs: Seq[Box[NodeSeq]] = urls.map(getUrl(url)).filter(_.isDefined) 
// or even 
val trueNodeseqs: Seq[NodeSeq] = urls.map(getUrl(url)).flatten 

使用OptionBox(或Either或scalaz」 Validation)爲您提供更多的方式權力決定何時處理問題比以往任何時候拋出異常可能。

有例外,你可能只能遍歷堆棧並捕獲它,如果你在類型中編碼失敗,只要你喜歡並且在你認爲最合適的情況下處理它,你可以隨身攜帶它。

+0

每個人都一直給我一個回答,可以追溯到你描述的這種情況。儘管在實踐中,當你編寫一個很少發生quire的API時, –

2

如果拋出一個異常,你唯一可以做的就是抓住它。所以,如果你的頁面的兩個部分拋出異常,你將永遠不會到達第二個。如果頁面的一部分返回Box碰巧是Failure,而第二部分不需要第一部分的返回值,則可以看到兩者。更一般地說,Box有一個有用的API,其中缺少Exception

+4

雅,這似乎是其中的原因。儘管我想的是一個失敗必須阻止你的情況。 David Pollak在他們的郵件列表上得到了一個很好的答案:http://goo.gl/5Lv7V –

相關問題