文章http://blogs.msdn.com/b/dotnet/archive/2009/08/25/the-good-and-the-bad-of-exception-filters.aspx表明F#本身支持异常过滤器(例如,在C#中没有语法)。异常过滤器在适当的catch块之前运行,如果它们返回true,则catch块将执行。我会想象F#会使用类似这样的东西
with
| ex when filter(ex) -> printfn "Caught"
然而,对我来说,它编译为通常的“catch [mscorlib] System.Object”,调用catch块中的filter函数,并且生成的MSIL中不存在“filter”部分。所以问题是,F#真的支持这种结构吗?
由于
答案 0 :(得分:4)
据我所知,F#实际上并没有实现/使用/公开MSIL中可用的filter
处理程序( ECMA-335,第5版,分区I,第12.4.2节“异常处理“)。根据{{3}}的第6.9.21节,编译器应该将整个with
子句编译成catch
块;将“fall-through”情况添加到已编译的代码中,以便如果捕获的异常与with
子句中的任何模式都不匹配,则会重新引发(通过rethrow
IL指令)。
那就是说,我真的很希望看到F#支持更多低级别的IL / CLR结构 - 它们不经常使用,但有时它们提供了正确实现方法的唯一方法,或者它们避免了复杂的解决方法;并且,与OP的情况一样,F#支持这些以实现互操作性非常重要。例如,try...fault
对于日志记录来说真的很方便,它会简化当前需要使用try...finally
和其他逻辑的一些代码(例如lock
中FSharp.Core
的实现{1}})。
更新:我只是在寻找有关完全不同主题的信息,并在2006年的Don博客上发表了这篇文章:F# 3.0 language specification(另见F# 1.1.13 now available!)。当然,F#1.1.13是该语言的非常早期版本,在那时它仍然是非常实验性的,但有趣的是看到编译器曾经有--generate-filter-blocks
个开关