2011-11-30 55 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 –

相关问题