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)catch returns :SECOND-THROW
>> The inner => :OUTER-CATCH
なし。
もしthrow
タグにマッチする有効なcatch
タグがないときは、 unwind
のスタックが実行され、 型control-error
のエラーが発生します。 もしエラーが発生した時は、 動的環境はthrow
の地点で有効なものになります。
block
, catch
, return-from
, unwind-protect
, 3.1. 評価
catch
とthrow
は通常、 退出点が動的スコープのとき(例えば、 throw
がレキシカルなcatch
に囲まれていないとき)に使われ、 それに対してblock
とreturn-from
は、 レキシカルスコープで十分のときに使用されます。