使用F#option
类型一段时间之后,我意识到它可以用于处理异常情况。我可以在以下示例中使用option
或Exception
:
find
函数会引发KeyNotFoundException
,而在这些情况下,相应的tryFind
对应函数会返回None
。我的印象是option
是一种功能更强大的方法,而Exception
在.NET平台中更常用。
在可用性,性能等方面,option
和Exception
在异常处理方面有何区别?在哪种情况下使用技术比使用其他技术更好?
答案 0 :(得分:15)
CLR使抛出和捕获异常的操作非常昂贵。仅仅因为这个原因,你应该更喜欢像Option这样的结构来报告预期的失败。如果失败确实异常且几乎无法恢复,请继续并抛出异常。但是正如你所注意到的那样,在搜索过程中回溯等事情并不常见,如果你用异常实现它们,你会发现你的表现会受到很大的影响。
因为这是CLR的一个属性,所以你是否在F#中并不重要。我的理解是ML类语言的其他运行时,例如ocaml,没有这个特性,因此可以更频繁地使用异常来控制流程。
答案 1 :(得分:8)
我的问题是在可用性,性能方面的异常处理中,Option和Exception之间有什么区别??
option
类型提供比异常更强的静态检查,增加了编译器捕获程序员错误的可能性。非异常返回可能比返回Some
结果更快,但异常返回比返回None
慢几百倍。
在哪种情况下使用技术比另一种更好?
每当我编写需要继续运行的服务器和守护进程之类的代码时,我会捕获尽可能多的异常并将其替换为option
等联合类型的值。然后,静态类型系统迫使我在几乎所有情况下都处理异常和非异常返回,这使得编写不会因意外传播的异常而死的代码变得更加容易。
答案 2 :(得分:5)
从理论的角度来看。 option
是你应该在那些纯粹从FP角度看的函数中使用的东西(你可以谷歌关于什么是纯函数)。例外更多的是关于不纯洁的世界(就像Haskell中的IO世界一样)。
现在从实际的角度来看,当你的应用程序的逻辑表明值可以存在或者不能存在时,我建议使用option
作为返回类型,即不存在的值是有效的应用程序规则。当应用程序逻辑中发生某些事件时,应该引发异常,这些事件表明逻辑执行不正确或者某些不正确的应用程序状态不符合应用程序规则。
从性能POV抛出异常比返回选项类型更昂贵(由于堆栈展开 - 寻找适当的异常处理程序等)。
答案 3 :(得分:4)
在可用性方面,我更喜欢F#中的选项。
选择是一种从根本上不同的思考特殊情况的方式,我相信有助于使F#特别。