gpt4 book ai didi

scala - Scala中抛出异常, "official rule"是什么

转载 作者:行者123 更新时间:2023-12-03 06:08:05 27 4
gpt4 key购买 nike

我正在 Coursera 上学习 Scala 类(class)。我也开始阅读 Odersky 的 Scala 书。

我经常听到的是,在函数式语言中抛出异常不是一个好主意,因为它破坏了控制流,并且我们通常返回一个失败或成功的“Either”。Scala 2.10 似乎也将提供朝着这个方向发展的 Try。

但是在书中和类(class)中,Martin Odersky 似乎并没有(至少现在)说异常是不好的,而且他经常使用它们。我还注意到方法断言/要求...

最后我有点困惑,因为我想遵循最佳实践,但它们不清楚,而且语言似乎是双向的......

有人可以解释一下在这种情况下我应该使用什么吗?

最佳答案

基本准则是对真正异常的事情使用异常**。对于“普通”故障,最好使用 OptionEither。如果您正在与 Java 进行交互,当有人以错误的方式打喷嚏时会抛出异常,您可以使用 Try 来保证自己的安全。

让我们举一些例子。

假设您有一个从 map 中获取某些内容的方法。可能会出什么问题?嗯,一些戏剧性和危险的事情,比如 segfault * 堆栈溢出,或者一些预期的事情,比如找不到元素。您可以让 segfault 堆栈溢出抛出异常,但如果您只是找不到元素,为什么不返回 Option[V] 而不是值或异常(或null)?

现在假设您正在编写一个程序,用户应该在其中输入文件名。现在,如果您不想在出现问题时立即放弃该计划,那么 Either 就是正确的选择:

def main(args: Array[String]) {
val f = {
if (args.length < 1) Left("No filename given")
else {
val file = new File(args(0))
if (!file.exists) Left("File does not exist: "+args(0))
else Right(file)
}
}
// ...
}

现在假设您要解析一个以空格分隔的数字的字符串。

val numbers = "1 2 3 fish 5 6"      // Uh-oh
// numbers.split(" ").map(_.toInt) <- will throw exception!
val tried = numbers.split(" ").map(s => Try(s.toInt)) // Caught it!
val good = tried.collect{ case Success(n) => n }

因此,您(至少)有三种方法来处理不同类型的故障:选项,它有效/无效,在不工作是预期行为的情况下,而不是令人震惊和警报失败; Either 用于当事情可以工作或不工作时(或者,实际上,任何有两个互斥选项的情况)并且您想要保存一些有关出错原因的信息;当您不想自己处理异常处理的整个麻烦,但仍需要与支持异常的代码进行交互时,请尝试

顺便说一句,异常(exception)是很好的例子——所以你会在教科书或学习 Material 中比在其他地方更常见地发现它们,我认为:教科书的例子通常是不完整的,这意味着通常可以通过以下方式避免的严重问题仔细的设计应该通过抛出异常来标记。

*编辑:段错误会导致 JVM 崩溃,无论字节码如何,都不应该发生;即使是异常(exception)也无法帮助你。我的意思是堆栈溢出。

**编辑:异常(没有堆栈跟踪)也用于 Scala 中的控制流——它们实际上是一种非常有效的机制,并且它们支持诸如库定义的 break 语句和一个从方法返回的 return,即使控件实际上已传递到一个或多个闭包中。大多数情况下,您自己不应该担心这一点,除非您意识到捕获所有 Throwable 并不是一个好主意,因为您可能会通过以下方式捕获这些控制流异常之一:错误。

关于scala - Scala中抛出异常, "official rule"是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12886285/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com