2.8阶控制例外 - 有什么意义?(scala 2.8 control Exception - wh

2019-09-02 07:27发布

在即将到来的Scala 2.8,一util.control软件包被添加,其中包括休息库和处理异常,这样的代码看起来像一个结构:

type NFE = NumberFormatException
val arg = "1"
val maybeInt = try { Some(arg.toInt) } catch { case e: NFE => None }

可以用类似的代码来代替:

import util.control.Exception._
val maybeInt = catching(classOf[NFE]) opt arg.toInt

我的问题是为什么呢? 这是什么增加比提供另一种(和完全不同)的方式来表达同样的事情,其他的语言? 有什么可使用新的控制而不是通过表达try-catch ? 是不是应该使异常处理在斯卡拉看起来像其他一些语言 (如果是的话,哪一个)一个DSL?

Answer 1:

有思考例外两种方式。 一种方法是把它们作为流量控制:一个异常改变程序的执行流程,使得从一个地方执行跳转到另一个。 第二种方式是把它们作为数据:一个例外是关于程序,其然后可以被用作输入到程序的其他部分的执行的信息。

try / catch在C ++和Java使用模式是非常多的第一类(*)的。

但是,如果您更愿意处理异常的数据,那么你就必须诉诸如图所示的一个代码,。 对于简单的情况下,这是相当容易的。 然而,当涉及到功能性的风格,其中成分为王,事情开始变得复杂。 你要么不得不各地复制代码,或者你滚你自己的库来处理它。

因此,其意是支持的功能和风格OO语言,人们不应该感到惊讶地看到治疗的异常数据库支持。

另请注意,是提供哦,所以,许多其他的可能性Exception处理事情。 你可以,例如,链catch处理器,在很多的方式,升降链的部分功能,可以很容易地委派对网页请求的处理责任。

这里是什么可以做一个例子,因为自动资源管理盛行,这些天:

def arm[T <: java.io.Closeable,R](resource: T)(body: T => R)(handlers: Catch[R]):R = (
  handlers 
  andFinally (ignoring(classOf[Any]) { resource.close() }) 
  apply body(resource)
)

它给你的资源的安全关闭(请注意使用忽略的),并且仍然适用,你可能希望使用任何醒目的逻辑。

(*)奇怪的是,Forth的异常控制, catchthrow ,就是其中的一个组合。 流程从跳throwcatch ,但随后这些信息作为数据处理。

编辑

好吧,好吧,我屈服。 我举一个例子。 一个例子,这就是它! 我希望这不是太做作,但有没有办法解决它。 这种事情会在大框架的最有用的,小样本不在家。

无论如何,让我们首先定义是与资源。 我决定上印刷线路和印刷返回线的数目,并且在这里是代码:

def linePrinter(lnr: java.io.LineNumberReader) = arm(lnr) { lnr =>
  var lineNumber = 0
  var lineText = lnr.readLine()
  while (null != lineText) {
    lineNumber += 1
    println("%4d: %s" format (lineNumber, lineText))
    lineText = lnr.readLine()
  }
  lineNumber
} _

下面是这个函数的类型:

linePrinter: (lnr: java.io.LineNumberReader)(util.control.Exception.Catch[Int]) => Int

所以, arm收到一个通用的可关闭的,但我需要一个LineNumberReader,所以当我调用这个函数,我需要传递。 我回报什么,但是,是一个功能Catch[Int] => Int ,这意味着我需要两个参数传递到linePrinter ,以得到它的工作。 让我们拿出一个Reader ,现在:

val functionText = """def linePrinter(lnr: java.io.LineNumberReader) = arm(lnr) { lnr =>
  var lineNumber = 1
  var lineText = lnr.readLine()
  while (null != lineText) {
    println("%4d: %s" format (lineNumber, lineText))
    lineNumber += 1
    lineText = lnr.readLine()
  }
  lineNumber
} _"""

val reader = new java.io.LineNumberReader(new java.io.StringReader(functionText))

所以,现在,让我们使用它。 首先,一个简单的例子:

scala> linePrinter(new java.io.LineNumberReader(reader))(noCatch)
   1: def linePrinter(lnr: java.io.LineNumberReader) = arm(lnr) { lnr =>
   2:          var lineNumber = 1
   3:          var lineText = lnr.readLine()
   4:          while (null != lineText) {
   5:            println("%4d: %s" format (lineNumber, lineText))
   6:            lineNumber += 1
   7:            lineText = lnr.readLine()
   8:          }
   9:          lineNumber
  10:        } _
res6: Int = 10

如果我再次尝试它,我得到这个:

scala> linePrinter(new java.io.LineNumberReader(reader))(noCatch)
java.io.IOException: Stream closed

现在假设我想如果有异常情况返回0。 我能做到这一点是这样的:

linePrinter(new java.io.LineNumberReader(reader))(allCatch withApply (_ => 0))

有趣的是在这里, 我完全解耦的异常处理 (该catch的一部分try / catch 从资源 ,这是通过做闭幕finally 。 此外,错误处理是一个值我可以传递给函数。 最起码,它使嘲讽try / catch / finally语句容易得多。 :-)

另外,我可以组合多种Catch使用or方法,所以我的代码,不同的层可以选择不同的异常添加不同的处理程序。 这确实是我的主要观点,但我无法找到一个异常丰富的界面(在短暂的时间我看了:)。

我将与有关的定义的话结束arm我给了。 这不是一个好。 特别是,我不能使用Catch方法,如toEithertoOption到结果,从改变R别的东西,这严重降低了使用的价值Catch它。 我不知道如何去改变,虽然。



Answer 2:

至于谁写的家伙,原因是组成和封装。 Scala编译器(和我打赌最体面的大小源基地)中充斥着这吞下所有异常的地方 - 你可以看到这些与-Ywarn渔获物 - 因为程序员是懒得列举相关的,这是可以理解的因为这很烦人。 由于能够定义,再利用,并撰写渔获物和finally块独立的试逻辑的,我希望能降低屏障写明智块。

而且,它不完全完成,我正在上万元的其他领域了。 如果你通过演员的代码,你可以看到巨大的剪切和粘贴的多重嵌套的try / catch / finally块的例子。 我/我不愿满足于try { catch { try { catch { try { catch ...

我的最终计划是拥有捕捞采取实际PartialFunction ,而不是需要case语句的文字列表,其中介绍的机会的一个全新的水平,即try foo() catch getPF()



Answer 3:

我会说这是最重要的表达风格问题。

除了比它的等效短,新捕()方法提供表达相同的行为一个功能更强大的方式。 尝试... catch语句通常被认为是势在必行的风格和异常被认为是副作用。 捕()把毯子铺在这个命令性代码从视图中隐藏。

更重要的是,现在我们有一个功能,那么它可以与其他的东西可以更容易地组成; 它可以被传递到其他高阶函数来创建更复杂的行为。 (你不能传递一个try ... catch语句具有参数化异常直接输入)。

看看这另一种方式是,如果斯卡拉没有提供这个醒目()函数。 那么最有可能的人将独立“重新发明”它,这会导致重复代码,并导致更多的非标码。 所以我觉得斯卡拉设计师认为这个功能是很常见,以保证它包括在标准Scala库。 (并且我同意)

亚历克斯



文章来源: scala 2.8 control Exception - what is the point?