异常处理中的选项与异常

pad*_*pad 10 .net f# exception-handling option

在使用F#option类型一段时间之后,我意识到它可以用于处理特殊情况.我可以使用optionException在以下示例中使用:

  1. findList/Array/Seq模块中的函数KeyNotFoundException在不常见的情况下引发,而相应的tryFind对应函数None在这些情况下返回.
  2. 当我进行回溯(解决N-queens,Sudoku等)时,每当分支没有解决方案时,我可以引发异常并稍后捕获它或返回None以匹配该值以回溯.在我们找到解决方案之前,这些情况经常发生.

我的印象是option更具功能性的方法,而Exception在.NET平台中更常用.

之间有什么区别optionException可用性,性能等方面的异常处理?在哪些情况下使用技术比使用另一种更好?

Seb*_*ood 15

CLR使抛出和捕获异常的操作非常昂贵.仅仅因为这个原因,你应该更喜欢像Option这样的结构来报告预期的失败.如果失败确实异常且几乎无法恢复,请继续并抛出异常.但是正如您所指出的那样,在搜索过程中回溯这些内容并不常见,如果您使用异常实现它们,您会发现性能会受到很大影响.

因为这是CLR的一个属性,所以你是否在F#中并不重要.我的理解是,类似ML的语言的其他运行时,例如ocaml,没有这个特性,因此可以更频繁地使用异常来控制流.


Jon*_*rop 8

我的问题是在可用性,性能方面的异常处理中,Option和Exception之间的区别是什么?

option类型提供比异常更强的静态检查,增加了编译器捕获程序员错误的可能性.非异常返回可能比返回Some结果更快,但异常返回比返回慢几百倍None.

在哪些情况下使用技术比另一种更好?

每当我编写需要继续运行的服务器和守护进程之类的代码时,我会捕获尽可能多的异常,并用union类型的值替换它们option.然后,静态类型系统迫使我在几乎所有情况下都处理异常和非异常返回,这使得编写不会因意外传播的异常而死的代码变得更加容易.


Ank*_*kur 5

从理论的角度来看.option你应该在那些纯粹从FP的观点中使用的功能中使用(你可以谷歌关于什么是纯函数).例外更多的是关于不纯净的世界(就像Haskell中的IO世界一样).

现在从实际的角度来看,option当你的应用程序的逻辑表明值可以存在或者不能存在时,我建议使用as返回类型,即不存在的值是有效的应用程序规则.当应用程序逻辑中发生某些事件时,应该引发异常,这些事件指示不正确的逻辑执行或某些不正确的应用程序状态,这与应用程序规则不符.

从性能POV抛出异常比返回选项类型更昂贵(由于堆栈展开 - 寻找适当的异常处理程序等).