このトピックでは、F# の例外処理に使用される式である try...with
式について説明します。
構文
try
expression1
with
| pattern1 -> expression2
| pattern2 -> expression3
...
注釈
try...with
式は、F# の例外を処理するために使用されます。 これは、C# の try...catch
ステートメントに似ています。 前の構文では、 expression1 のコードで例外が生成される可能性があります。
try...with
式は値を返します。 例外がスローされない場合、式全体が expression1 の値を返します。 例外がスローされると、各 パターン が例外と順番に比較され、最初の一致パターンでは、その分岐に対応する 式 ( 例外ハンドラーと呼ばれます) が実行され、その例外ハンドラー内の式の値が全体的に返されます。 パターンが一致しない場合、例外は一致するハンドラーが見つかるまで呼び出し履歴を伝達します。 例外ハンドラーの各式から返される値の型は、 try
ブロック内の式から返される型と一致する必要があります。
多くの場合、エラーが発生したという事実は、各例外ハンドラーの式から返すことができる有効な値がないことを意味します。 頻繁なパターンは、式の型をオプション型にすることです。 次のコード例は、このパターンを示しています。
let divide1 x y =
try
Some (x / y)
with
| :? System.DivideByZeroException -> printfn "Division by zero!"; None
let result1 = divide1 100 0
例外は .NET 例外でも、F# 例外でもかまいません。
exception
キーワードを使用して F# 例外を定義できます。
さまざまなパターンを使用して、例外の種類やその他の条件をフィルター処理できます。オプションの概要を次の表に示します。
パターン | 説明 |
---|---|
:? exception-type | 指定した .NET 例外の種類と一致します。 |
:? 識別子としての exception-type | 指定した .NET 例外の種類と一致しますが、例外に名前付き値を指定します。 |
exception-name(arguments) | F# 例外の型と一致し、引数をバインドします。 |
識別子 | 任意の例外に一致し、名前を例外オブジェクトにバインドします。 :? と同じです。識別子としての System.Exception |
条件時の識別子 | 条件が true の場合、例外と一致します。 |
例示
次のコード例は、さまざまな例外ハンドラー パターンの使用を示しています。
// This example shows the use of the as keyword to assign a name to a
// .NET exception.
let divide2 x y =
try
Some( x / y )
with
| :? System.DivideByZeroException as ex -> printfn "Exception! %s " (ex.Message); None
// This version shows the use of a condition to branch to multiple paths
// with the same exception.
let divide3 x y flag =
try
x / y
with
| ex when flag -> printfn "TRUE: %s" (ex.ToString()); 0
| ex when not flag -> printfn "FALSE: %s" (ex.ToString()); 1
let result2 = divide3 100 0 true
// This version shows the use of F# exceptions.
exception Error1 of string
exception Error2 of string * int
let function1 x y =
try
if x = y then raise (Error1("x"))
else raise (Error2("x", 10))
with
| Error1(str) -> printfn "Error1 %s" str
| Error2(str, i) -> printfn "Error2 %s %d" str i
function1 10 10
function1 9 2
注
try...with
コンストラクトは、try...finally
式とは別の式です。 したがって、コードで with
ブロックと finally
ブロックの両方が必要な場合は、2 つの式を入れ子にする必要があります。
注
非同期式、タスク式、およびその他の計算式で try...with
を使用できます。その場合は、カスタマイズされたバージョンの try...with
式が使用されます。 詳細については、「 非同期式、 タスク式、 およびコンピュテーション式」を参照してください。
こちらも参照ください
.NET