例外を使用できます。
内側の if またはループで Abort を呼び出し、続行したい場所で EAbort 例外をキャッチします
procedure ...
begin
try
if .... then
begin
(* here the code to execute *)
if I_want-to-exit then Abort;
(* here the code not to execute if has exited *)
end;
except on E: EABORT do ;
end;
(* here the code to execute *)
end;
アップデート。誰かがこれに賛成しました。トピックはずっと前に埋葬されていないようです。わかりました、それからあちこちのコメントに埋もれていたものの簡単な要約を与えます。
このアプローチは、Marjan の try-exit-finally よりも劣る可能性があります。彼の回答を参照してください: https://stackoverflow.com/a/11689392/976391
例外は、Delphi ではいくらか安価です。Borland はこれに関する特許をほとんど保有していませんが、それでも+finally
よりも高速に実行される可能性があります。raise
except
OTOH、このアプローチは、例外のキャンセルと異なるクラスを使用できるため、いくつかのネストされた終了可能な if ブロックと異なる終了ターゲットを持つように一般化できます。そして、except-block が単なる終了アンカーであり、実際のコードがその内部ではなくその後ろにある場合 (finally-solution に必要なように)、コードが少しきれいになり、開発者 (トピックの開始者) の一連の思考をより適切に表現しているように感じます。 )。
type EExitException1 = class(Exception) end;
type EExitException2 = class(Exception) end;
procedure ...
begin
try
if .... then
begin
(* here the code to execute *)
try
if .... then
begin
(* here the nested code to execute *)
if I_want-to-exit then raise EExitException1.Create();
(** ... **)
if I_want-to-exit-far-away then raise EExitException2.Create();
(* here the code not to execute if if-block cancelled *)
end; // if
(* here the code to execute *)
if I_want-to-exit-outer-if-here then raise EExitException2.Create();
(* here the code not to execute *)
except on E: EExitException1 do ; end; // killing the exception
(* here the code to execute after the outer if-block exit *)
end;
(* one more piece of skippable code *)
except on E: EExitException2 do ; end;
(* here the code to execute yet again *)
end;
ただし、この一般化は、別の種類のスパゲッティにも急速に変化する傾向があります。
確かに、問題そのものは厄介なようで、全体のリファクタリングが必要です。すべてのソリューションをリファクタリングしないと、何らかの形で面倒になります。はしご、普通の古いgoto
、旗の vars の場合 - あなたの毒を選んでください。どちらが醜くないかは死ぬまで議論できますが、それらはすべて醜いです.