8

文章https://devblogs.microsoft.com/dotnet/the-good-and-the-bad-of-exception-filters/表明 F# 本身支持异常过滤器(例如,在 C# 中没有语法)。异常过滤器在适当的 catch 块之前运行,如果它们返回 true,则将执行 catch 块。我会想象 F# 使用类似这样的东西来做到这一点

with
    | ex when filter(ex) -> printfn "Caught"

但是,对我来说,它通过调用 catch 块内的过滤器函数编译为通常的“catch [mscorlib]System.Object”,并且生成的 MSIL 中不存在“过滤器”部分。所以问题是,F# 真的支持这种结构吗?

谢谢

4

1 回答 1

4

据我所知,F# 实际上并没有实现/使用/公开filterMSIL 中可用的处理程序(ECMA-335,第 5 版,Partition I,第 12.4.2 节“异常处理”)。根据F# 3.0 语言规范第 6.9.21 节,编译器应该将整个with子句编译成一个catch块;在编译后的代码中添加了一个“失败”情况,以便如果捕获的异常与子句中的任何模式都不匹配with,它会被重新引发(通过rethrowIL 指令)。

也就是说,我真的很希望看到 F# 支持更多的低级 IL/CLR 构造——它们不经常使用,但有时它们提供了正确实现某些东西的唯一方法,或者它们避免了对复杂解决方法的需要;并且,在 OP 的情况下,F# 支持这些以实现互操作性很重要。例如,try...fault对于日志记录来说真的很方便,它会简化一些当前需要try...finally与附加逻辑一起使用的代码(例如,lockin的实现FSharp.Core)。

更新:我只是在四处寻找有关完全不同主题的信息,并在 Don 的博客上看到了 2006 年的这篇文章:F# 1.1.13 now available!(另请参阅随附的发行说明)。当然,F# 1.1.13 是该语言的一个非常早期的版本,当时它还处于试验阶段,但有趣的是,编译器曾经有一个--generate-filter-blocks开关。

于 2013-09-02T13:04:42.383 回答