2011-10-31 40 views
10

在使用F#option类型一段时间后,我意识到它可以用于处理异常情况。我可以在以下实施例中使用两种或optionException选项vs异常处理异常

  1. find功能从列表/阵列/ SEQ模块在罕见的情况下提高KeyNotFoundException,而对应tryFind同行在这些情况下返回None
  2. 当我回溯(在解决N皇后,数独等),只要分支无解,我可以抛出一个异常,后来将其接住或返回无以匹配值原路返回。这些情况经常发生,直到我们找到解决方案。

我的印象是option是一种更为实用的方法,而Exception更常用于.NET平台。

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

回答

15

的CLR使得抛出和捕获异常极其昂贵的操作。仅仅因为这个原因,你应该更喜欢Option这样的结构来报告预期的失败。如果失败确实是例外并且几乎无法恢复,请继续并引发异常。但正如你所看到的那样,在搜索过程中回溯等事情是无所作为的,而且如果你用例外来实现它们,你会发现你的性能会受到很大的影响。

因为这是CLR的一个属性,它并没有真正不管你是在F#与否。我的理解是ML类语言的其他运行时间,例如ocaml,没有这个特性,所以可能更多地使用异常来控制流量。

+0

事实上,我曾测量过这一点,发现C++异常比OCaml慢6倍,而.NET的速度比OCaml慢600倍! –

5

从理论上来看。 option是你应该在那些纯粹从FP角度来看的函数中使用的东西(你可以在谷歌中了解什么是纯函数)。例外情况更多的是关于不纯的世界(像哈斯克尔的IO世界)。

现在从实际的角度来看,我建议使用option作为返回类型,当你的应用程序的逻辑表示该值可以在那里,或者它不能存在的值是一个有效的应用程序规则。当应用程序逻辑中发生错误的逻辑执行或者某些不正确的应用程序状态(应用程序规则不符合预期)时,应该引发异常。

从性能POV抛出的例外是更昂贵的(因为栈展开 - 寻找适当的异常处理 - 等)相比,恢复选项类型为。

+0

我不同意关于表演的评论。选项类型比Exception类型更轻量级(请参阅@Sebastian Good的答案)。 – pad

+0

我的文字说'异常会坏'..这意味着异常在性能上不好 – Ankur

+0

对不起,我的错误是不仔细阅读:) – pad

4

就可用性而言,我更喜欢F#中的选项。

  • 选项封装了异常状态以及预期状态。这允许您在处理异常状态之前处理异常状态,直到您需要预期状态为止。
  • 选项也有一个helper functions的数字,你必须自己写例外。
  • Partial Active Patterns允许您使用选项非常干净地处理多个特殊情况。在F#中的
  • Optional Paramaters使用Options实现。我上面提到的这种延迟性质可以让您不在意是什么产生了特例,只要消费者具有默认值即可。

选项是一个从根本上不同的思维方式的特殊情况下,我相信有助于使F#特殊。

+0

对于一个非常深思熟虑的答案+1。这就是我想知道的有关在异常处理中使用选项的信息。 – pad

8

我的问题是什么是异常处理的可用性,性能方面的选项和异常之间的区别...?

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

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

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