% 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
は、
レキシカルスコープで十分のときに使用されます。