作为一名Java程序员,我一直对Unchecked Exception持批评态度。通常,程序员使用它作为编码简便性的途径,只会在以后造成麻烦。此外,与未检查的对等程序相比,具有检查的异常的程序(尽管不整洁)非常健壮。
令人惊讶的是,在Scala中,没有什么叫做“检查的异常”。Scala中所有未选中和未选中的Java都未选中。
做出此决定的动机是什么?对我来说,在使用任何外部代码时都会遇到很多问题。并且,如果偶然地文档很差,则将导致KILL。
作为一名Java程序员,我一直对Unchecked Exception持批评态度。通常,程序员使用它作为编码简便性的途径,只会在以后造成麻烦。此外,与未检查的对等程序相比,具有检查的异常的程序(尽管不整洁)非常健壮。
令人惊讶的是,在Scala中,没有什么叫做“检查的异常”。Scala中所有未选中和未选中的Java都未选中。
做出此决定的动机是什么?对我来说,在使用任何外部代码时都会遇到很多问题。并且,如果偶然地文档很差,则将导致KILL。
Answers:
检查异常通常被视为失败。请注意,在Java采用它们之后,不会创建任何语言。参见http://www.artima.com/intv/handcuffs2.html, http://googletesting.blogspot.ru/2009/09/checked-exceptions-i-love-you-but-you.html,HTTP:/ /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.exception
或scala.util.Try
(从Scala 2.10开始)。
try..catch
似乎比更具可读性if
。更重要的是,我还可以保证那些大多数开发人员不会编写返回错误结果的代码-在Scala中太复杂-您甚至都无法从函数中返回(就像在Pascal中一样)
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.*
)中大多数(全部?)新功能接口中的方法也不会声明未经检查的异常。