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 [mscorlib]System.Object」にコンパイルされ、catch ブロック内のフィルター関数が呼び出され、生成された MSIL に「フィルター」セクションが存在しません。問題は、F# がこの構造を本当にサポートしているのかということです。

ありがとう

4

1 に答える 1

4

私の知る限り、F# はfilterMSIL で利用可能なハンドラーを実際に実装/使用/公開していません ( ECMA-335、第 5 版、パーティション I、セクション 12.4.2「例外処理」 )。F# 3.0 言語仕様のセクション 6.9.21 によると、コンパイラはwith句全体をcatchブロックにコンパイルすることになっています。コンパイルされたコードに「フォールスルー」ケースが追加され、キャッチされた例外が句のパターンのいずれとも一致しない場合に( IL 命令withを介して) 再発生します。rethrow

とは言っても、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 に答える