F#-例外処理
例外は、プログラムの実行中に発生する問題です。F#例外は、ゼロ除算の試行など、プログラムの実行中に発生する例外的な状況への応答です。
例外は、プログラムのある部分から別の部分に制御を移す方法を提供します。F#例外処理は、次の構成を提供します-
構築する | 説明 |
---|---|
exprを上げる | 指定された例外を発生させます。 |
exprで失敗 | を上げる System.Exception 例外。 |
ルールでexprを試してください | パターンルールに一致する式をキャッチします。 |
exprを最後にexprを試してください | 実行 finally 計算が成功したときと例外が発生したときの両方の式。 |
| :?ArgumentException | 指定された.NET例外タイプに一致するルール。 |
| :?eとしてのArgumentException | 指定された.NET例外タイプに一致し、名前をバインドするルール e 例外オブジェクト値に。 |
| 失敗(msg)→expr | 指定されたデータを運ぶF#例外に一致するルール。 |
| exn→expr | 名前をバインドする、任意の例外に一致するルール exn 例外オブジェクト値に。 |
| expr→exprの場合のexn | 指定された条件下で例外に一致し、名前をバインドするルール exn 例外オブジェクト値に。 |
例外処理の基本的な構文から始めましょう。
構文
F#例外処理ブロックの基本的な構文は次のとおりです。
exception exception-type of argument-type
どこ、
exception-type 新しいF#例外タイプの名前です。
argument-type このタイプの例外を発生させたときに指定できる引数のタイプを表します。
引数タイプにタプル型を使用すると、複数の引数を指定できます。
ザ・ try...with 式は、F#言語での例外処理に使用されます。
try…with式の構文は次のとおりです。
try
expression1
with
| pattern1 -> expression2
| pattern2 -> expression3
...
ザ・ try...finally 式を使用すると、コードのブロックが例外をスローした場合でも、クリーンアップコードを実行できます。
tryの構文…finally式は-
try
expression1
finally
expression2
ザ・ raise関数は、エラーまたは例外的な状態が発生したことを示すために使用されます。また、例外オブジェクトのエラーに関する情報も取得します。
raise関数の構文は次のとおりです。
raise (expression)
ザ・ failwith 関数はF#例外を生成します。
failwith関数の構文は次のとおりです。
failwith error-message-string
ザ・ invalidArg 関数は引数例外を生成します。
invalidArg parameter-name error-message-string
例外処理の例
例1
次のプログラムは、単純な試行による基本的な例外処理を示しています…ブロック-
let divisionprog x y =
try
Some (x / y)
with
| :? System.DivideByZeroException -> printfn "Division by zero!"; None
let result1 = divisionprog 100 0
プログラムをコンパイルして実行すると、次の出力が生成されます。
Division by zero!
例2
F#は exception例外を宣言するためのタイプ。のフィルターで直接例外タイプを使用できます。try...with 式。
次の例はこれを示しています-
exception Error1 of string
// Using a tuple type as the argument type.
exception Error2 of string * int
let myfunction x y =
try
if x = y then raise (Error1("Equal Number Error"))
else raise (Error2("Error Not detected", 100))
with
| Error1(str) -> printfn "Error1 %s" str
| Error2(str, i) -> printfn "Error2 %s %d" str i
myfunction 20 10
myfunction 5 5
プログラムをコンパイルして実行すると、次の出力が生成されます。
Error2 Error Not detected 100
Error1 Equal Number Error
例3
次の例は、ネストされた例外処理を示しています-
exception InnerError of string
exception OuterError of string
let func1 x y =
try
try
if x = y then raise (InnerError("inner error"))
else raise (OuterError("outer error"))
with
| InnerError(str) -> printfn "Error:%s" str
finally
printfn "From the finally block."
let func2 x y =
try
func1 x y
with
| OuterError(str) -> printfn "Error: %s" str
func2 100 150
func2 100 100
func2 100 120
プログラムをコンパイルして実行すると、次の出力が生成されます。
From the finally block.
Error: outer error
Error:inner error
From the finally block.
From the finally block.
Error: outer error
例4
次の関数は、 failwith 関数-
let divisionFunc x y =
if (y = 0) then failwith "Divisor cannot be zero."
else
x / y
let trydivisionFunc x y =
try
divisionFunc x y
with
| Failure(msg) -> printfn "%s" msg; 0
let result1 = trydivisionFunc 100 0
let result2 = trydivisionFunc 100 4
printfn "%A" result1
printfn "%A" result2
プログラムをコンパイルして実行すると、次の出力が生成されます。
Divisor cannot be zero.
0
25
例5
ザ・ invalidArg関数は引数例外を生成します。次のプログラムはこれを示しています-
let days = [| "Sunday"; "Monday"; "Tuesday"; "Wednesday"; "Thursday"; "Friday"; "Saturday" |]
let findDay day =
if (day > 7 || day < 1)
then invalidArg "day" (sprintf "You have entered %d." day)
days.[day - 1]
printfn "%s" (findDay 1)
printfn "%s" (findDay 5)
printfn "%s" (findDay 9)
プログラムをコンパイルして実行すると、次の出力が生成されます。
Sunday
Thursday
Unhandled Exception:
System.ArgumentException: You have entered 9.
…
システムによっては、システムでエラーを引き起こしているファイルと変数に関するその他の情報も表示されます。