fparsecというパーサに手を出してみましたが、まだ力不足で使いこなせる気がしなかったので基本に戻ってきました。今日は悲しいかな例外です。
例外は、C#の例外と同じものだと思ってもらってOKだと思います。私はそう思ってます。F#での例外の定義の仕方は、とても簡単です。
exception 型名 of タプル
みたいな感じで定義できます。試しに例外作って投げてみましょう。投げるにはraise関数を使います。
// 例外定義して exception Error1 of string // 投げるだけ raise (Error1("だめぽ"))
必ず例外が出るので見慣れたスタックフローが表示されます。
ハンドルされていない例外: Program+Error1: 種類 'Program+Error1' の例外がスローさ れました。 場所 Microsoft.FSharp.Core.Operators.Raise[T](Exception exn) 場所 <StartupCode$ConsoleApplication29>.$Program.main@() 場所 c:\users\kazuki \documents\visual studio 2010\Projects\ConsoleApplication29\ConsoleApplication29 \Program.fs:行 6
因みに、例外は投げたからにはキャッチするのが王道です。F#での例外のキャッチにはtry with文を使います。withの部分でパターンマッチで例外を判別します。
// 例外定義して exception Error1 of string try // 投げるだけ raise (Error1("だめぽ")) with | Error1 (s) -> printfn "%s" s
例外に複数の情報を持たせたかったらタプルなのでいくつでも増やすことが出来ます。試しに2つに増やしてみます。
// 例外定義して exception Error1 of string * int try // 投げるだけ raise (Error1("だめぽ", 1)) with // 普通にパターンマッチできる | Error1 (s, 0) -> printfn "0: %s" s | Error1 (s, 1) -> printfn "1: %s" s
1: だめぽ
次に.NET Frameworkの例外も捕まえてみようと思います。皆大好きNullReferenceExceptionを投げてみます。キャッチのほうは変数名を書くだけでキャッチ出来ます。
open System try // 投げるだけ raise (NullReferenceException("ぬるり")) with // 変数に入れてキャッチ | e -> printfn "%s" e.Message
型指定でキャッチする例外を仕分けすることもできます。
open System try // 投げるだけ raise (NullReferenceException("ぬるり")) with // 型名でパターンマッチできる | :? ArgumentException as e -> printfn "引数だめよ" | :? NullReferenceException as e -> printfn "%s" e.Message
いい感じ。キャッチした例外の再スローはreraiseという関数があるのでこれを使うのがいいらしいです。
そして最後にfinallyです。これは何故こうなったのか謎で仕方ないのですがtry withとは別物扱いなので例外時も通常時も最後に固定の処理をやりたいという要件のときにはtry withをtry finallyで囲わないといけません。
open System try try // 投げるだけ raise (NullReferenceException("ぬるり")) with // 型名でパターンマッチできる | :? ArgumentException as e -> printfn "引数だめよ" | :? NullReferenceException as e -> printfn "%s" e.Message finally printfn "ふぁいなりー"
ちょっとめんどくさいですね・・・実行するとふぁいなりーの処理が走ってるのがわかります。
ぬるり ふぁいなりー
おおざっぱには説明しましたが、細かい所をもっと勉強したいという人はMSDNをあたるのが一番です。
failwithやinvalidArg関数の使い方とかは、ここではやってないのでMSDNの例を見てみるのがいいと思います(力尽きた)
過去記事
- 手軽なスクリプト言語としてのF#
- 手軽なスクリプト言語としてのF# その2
- 手軽なスクリプト言語としてのF# その3
- 手軽なスクリプト言語としてのF# その4
- 手軽なスクリプト言語としてのF# その5
- 手軽なスクリプト言語としてのF# その6
- 手軽なスクリプト言語としてのF# その7
- 手軽なスクリプト言語としてのF# その8「レコード」
- 手軽なスクリプト言語としてのF# その9「クラス」
- 手軽なスクリプト言語としてのF# その10「継承・アブストラクトクラス」
- 手軽なスクリプト言語としてのF# その11「インターフェースと演算子のオーバーロード」
- 手軽なスクリプト言語としてのF# その12「ラムダ式とイベント」
- 手軽なスクリプト言語としてのF# その13「オブジェクト初期化子みたいなの」
- 手軽なスクリプト言語としてのF# その14「合成演算子とパイプ演算子」
- 手軽なスクリプト言語としてのF# その15「WPFしてみた」
- 手軽なスクリプト言語としてのF# その16「総称型 ジェネリック」
- 手軽なスクリプト言語としてのF# その17「リスト」
- 手軽なスクリプト言語としてのF# その18「オプション型」
- 手軽なスクリプト言語としてのF# その19「参照型よりオプション型って安全?」
- 手軽なスクリプト言語としてのF# その20「パターンマッチ」
- 手軽なスクリプト言語としてのF# その21「再帰とループ」
- 手軽なスクリプト言語としてのF# その22「列挙型」
- 手軽なスクリプト言語としてのF# その23「アクティブパターン」
- F# + WPF + MVVM で足し算アプリ
- 手軽なスクリプト言語としてのF# その24「シーケンス」
- 手軽なスクリプト言語としてのF# その25「判別共用体」