Fsharp-exception-handling
F#-例外処理
例外は、プログラムの実行中に発生する問題です。 F#例外は、ゼロ除算の試行など、プログラムの実行中に発生する例外的な状況への応答です。
例外は、プログラムのある部分から別の部分に制御を移す方法を提供します。 F#の例外処理は、次の構成を提供します-
Construct | Description |
---|---|
raise expr | Raises the given exception. |
failwith expr | Raises the *System.Exception *exception. |
try expr with rules | Catches expressions matching the pattern rules. |
try expr finally expr | Execution the* finally *expression both when the computation is successful and when an exception is raised. |
:? ArgumentException | |
A rule matching the given .NET exception type. | |
:? ArgumentException as e | A rule matching the given .NET exception type, binding the name* e *to the exception object value. |
Failure(msg) → expr | |
A rule matching the given data-carrying F# exception. | |
exn → expr | A rule matching any exception, binding the name* exn *to the exception object value. |
exn when expr → expr |
例外処理の基本的な構文から始めましょう。
構文
F#例外処理ブロックの基本的な構文は-
exception exception-type of argument-type
どこで、
exception-type は、新しいF#例外タイプの名前です。
argument-type は、この型の例外を発生させるときに指定できる引数の型を表します。
argument-typeにタプル型を使用して、複数の引数を指定できます。
*try ... with* 式は、F#言語での例外処理に使用されます。
式を使用したtry…の構文は-
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
次のプログラムは、ブロックを使用した単純なtry…による基本的な例外処理を示しています-
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.
…
システムによっては、システムでエラーの原因となっているファイルと変数に関するその他の情報も表示されます。