% Special-Operator THROW
Special Operator THROW
throw tag result-form =>|
tag - catchのタグ、評価されます。
result-form - フォーム、下記の説明どおり評価されます。
throwは、tagとeqで等しいタグのcatchへ、
非局所的な制御の遷移を行います。
最初にtagが評価され、throwタグと呼ばれるオブジェクトを生成します。
そのあとresult-formが評価され、その値は保存されます。
もしresult-formが多値を生成したときは、その全ての値が保存されます。
もっとも近くにあるtagとeqで等しい
throwタグを持つ有効なcatchに対して退出が行われます。
そのとき保存された値は、catchの返却値か多値として返されます。
throwによって開始される制御の遷移の実行についての説明は、
5.2. 終了地点への制御の遷移をご確認ください。
(catch 'result
(setq i 0 j 0)
(loop (incf j 3) (incf i)
(if (= i 3) (throw 'result (values i j))))) => 3, 9
(catch nil
(unwind-protect (throw nil 1)
(throw nil 2))) => 2
下記の例ではbのcatchの上を最初のthrowによって通過しているため、
結果は未定義であり、したがって移植可能なプログラムは
動的エクステントが終了していると仮定してください。
catchタグの束縛はまだ解除されていないので、
これは2番目のthrowのターゲットです。
(catch 'a
(catch 'b
(unwind-protect (throw 'a 1)
(throw 'b 2))))
下記の例は「The inner catch returns :SECOND-THROW」が出力され、
:outer-catchが返却されます。
(catch 'foo
(format t "The inner catch returns ~s.~%"
(catch 'foo
(unwind-protect (throw 'foo :first-throw)
(throw 'foo :second-throw))))
:outer-catch)
>> The inner catch returns :SECOND-THROW
=> :OUTER-CATCH
なし。
もしthrowタグにマッチする有効なcatchタグがないときは、
unwindのスタックが実行され、
型control-errorのエラーが発生します。
もしエラーが発生した時は、
動的環境はthrowの地点で有効なものになります。
block,
catch,
return-from,
unwind-protect,
3.1. 評価
catchとthrowは通常、
退出点が動的スコープのとき(例えば、
throwがレキシカルなcatchに囲まれていないとき)に使われ、
それに対してblockとreturn-fromは、
レキシカルスコープで十分のときに使用されます。