Fsharp-exception-handling

提供:Dev Guides
移動先:案内検索

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.
…

システムによっては、システムでエラーの原因となっているファイルと変数に関するその他の情報も表示されます。