Scala中未经检查的异常的决定


17

作为一名Java程序员,我一直对Unchecked Exception持批评态度。通常,程序员使用它作为编码简便性的途径,只会在以后造成麻烦。此外,与未检查的对等程序相比,具有检查的异常的程序(尽管不整洁)非常健壮。

令人惊讶的是,在Scala中,没有什么叫做“检查的异常”。Scala中所有未选中和未选中的Java都未选中。

做出此决定的动机是什么?对我来说,在使用任何外部代码时都会遇到很多问题。并且,如果偶然地文档很差,则将导致KILL。


11
作为一名Java程序员,我一直对检查异常持批评态度。不整洁的代码永远不会健壮。
Michael Borgwardt 2012年

Answers:


28

检查异常通常被视为失败。请注意,在Java采用它们之后,不会创建任何语言。参见http://www.artima.com/intv/handcuffs2.html http://googletesting.blogspot.ru/2009/09/checked-exceptions-i-love-you-but-you.htmlHTTP:/ /www.mindview.net/Etc/Discussions/CheckedExceptions等。

特别是,它们是不可组合的(除非恢复为throws Exception)。

在斯卡拉你有一个更好的选择:使用代数类型的返回值,例如Option[T]Either[Exception, T],自己的类型,当你希望用户来处理特定情况下(例如,而不是

def foo: Int // throws FileNotFoundException, IllegalStateException

你有

sealed trait FooResult
case class Success(value: Int) extends FooResult
case class FileNotFound(file: File) extends FooResult
case object IllegalState extends FooResult

def foo: FooResult

并且现在需要消费者处理所有结果)

要处理确实引发异常的外部代码,您可以使用scala.util.control.exceptionscala.util.Try(从Scala 2.10开始)。


4
从来没有理解过,大多数人不处理检查异常的参数。大多数人都不是优秀的开发人员。我保证大多数开发人员都不会处理错误结果。实际上,try..catch似乎比更具可读性if。更重要的是,我还可以保证那些大多数开发人员不会编写返回错误结果的代码-在Scala中太复杂-您甚至都无法从函数中返回(就像在Pascal中一样)
Pijusn

5
我发现您的评论令人困惑,缺乏证据,@ Pius。在Scala中,选择Option作为返回类型可能会导致模式匹配,而不是If语句。以这种样式返回None而不是Some是微不足道的,而不是复杂的。不太聪明的开发人员可能不会选择编写返回代数类型的函数,但这是另一回事。最后,“您甚至无法在任何需要的时候从函数返回”-简直是不正确的。
itsbruce 2014年

7

Java中的检查异常并不是一件坏事。当然,对于Scala,ADT可能是更好的选择,但是在Java中,检查异常有其位置,整齐的代码参数毫无意义,无论有多少博客重复。它基本上说您应该愉快地忽略系统中可能发生的严重且可能可修复的状况,因为螺丝型系统,漂亮的代码可使您的系统自动健壮。这样的推理也解释了为什么如此多的Java程序员自愿将其代码移入XML(Spring,Maven等。不过我错过了其中的漂亮部分)。

M. Odersky在http://www.scala-lang.org/old/node/8787.html下方给出的Scala中缺少检查异常的原因毫不奇怪,这是很合理的。

列表中的map方法可以最好地证明检查异常的问题:

def map[B](f: A => B): List[B]

如何用@throws注释地图?如果map本身未获得@throws批注,则可能无法将具有@throws的任何函数传递给map。这将给地图的使用方式带来繁琐的限制和区别。如果我们能以某种方式声明map抛出其函数参数抛出的所有异常,情况将会更好。有一些效果系统可以表达这一点,但是到目前为止,我所看到的每个符号都太沉重了。

卢卡斯·瑞兹(Lukas Rytz)正在对轻量级效果系统进行一些研究,这些系统可用于以简明而精确的方式表示地图的类型和其他常用功能。这是研究,因此目前尚不清楚我们将在多大程度上成功,以及其中有多少可以投入Scala。理想情况下,我们可以在某个时候将其添加为可选类型系统。但是做出具体的预测还为时过早。

干杯

不确定,但我认为Java 8 lambda也仅限于未经检查的异常。JDK 8(java.util.function.*)中大多数(全部?)新功能接口中的方法也不会声明未经检查的异常。


2

如果要提高效率,就必须放弃..精度/控制<-我需要一个更好的词。

就抽象而言,Scala位于顶部。如果Scala的目标之一是摆脱烦人的样板代码,那么显而易见的地方就是Java的异常处理。如果要用Java编写快速代码,只需不断抛出已检查的异常,直到它们击中main()并有效地变为未检查状态。

我不知道我是否完全了解您的要求,但这是我认为最明显的原因。

好吧,我做了一点看,有人写了关于检查异常的悲剧

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.