try catch
チュートリアルに出てこなかったので、例外の投げ方と捕捉方法について調べてみました。
- Erlangにもtry .. catchによる例外処理の仕組みがあります。
- JavaScriptと同様にthrow()で任意のオブジェクトを例外?として発生させることができます。
- 発生した例外はcatchで捕捉でき、パターンマッチによって処理を切り分けることが可能です。
- Javaのfinallyに相当する機能も提供されています。
try構文
以下の形式で書きます。
try <処理1>, <処理2> catch [<クラス>:]<パターン1> [when <ガード条件>] -> <例外発生時の処理>; [<クラス>:]<パターン2> [when <ガード条件>] -> <例外発生時の処理> after <必ず実行したい処理> end
- <処理1>,<処理2>の部分に例外を捕捉したい処理を書きます。
- この処理で例外が発生した場合、catchの中に進みます。
- 例外が発生しなかった場合、これの評価値がtry構文全体の値となります。
- <処理1>,<処理2>で例外が発生した場合、catchのパターンが評価されます。
- 例外とマッチするパターンがあった場合、それに続く処理が実行されます。
- クラスの部分には次の3つを指定でき、ハンドリングする例外の種類を指定できます。省略した場合、「throw」が指定されたと見なされます。
- throw
- error
- exit
- afterを指定すると、try構文を抜ける際に、それに続く処理が必ず実行されます。
だいたい、Javaとかと似た感じですね。例によって";"のあるなしがややこしいので注意。
サンプル
-module(try_catch). -export([try_catch/1]). try_catch( V ) -> try try_catch0( V ) catch error:Reason -> io:format( "catch error: ~w~n", [Reason] ); throw:throwable1 -> io:format( "catch throwable~n", [] ) after io:format( "end~n", [] ) end. try_catch0( V ) -> case V of success -> V; error -> 1/0; throw1 -> throw(throwable1); % throw()で例外を投げる。 throw2 -> throw(throwable2) end.
実行結果です。
2> try_catch:try_catch(success). end success 3> try_catch:try_catch(error). catch error: badarith end ok 4> try_catch:try_catch(throw1). catch throwable end ok 5> try_catch:try_catch(throw2). end =ERROR REPORT==== 22-Nov-2007::21:59:55 === Error in process <0.29.0> with exit value: {{nocatch,throwable2},[{try_catch,tr _catch0,1},{erl_eval,do_apply,5},{shell,exprs,6},{shell,eval_loop,3}]} ** exited: {{nocatch,throwable2}, [{try_catch,try_catch0,1}, {erl_eval,do_apply,5}, {shell,exprs,6}, {shell,eval_loop,3}]} ** 6>