Windows バッチ スクリプトの GOTO は、一般的に安全に使用でき、場合によっては必要になります。ただし、注目に値する 3 つの非直感的な設計機能があります。
1) 括弧で囲まれたコード ブロック内に配置されたラベルに GOTO しないでください
括弧で囲まれたブロック内に配置されたラベルに GOTO できますが、意図した結果が得られない可能性があります。たとえば、FOR ループの DO ブロック内で GOTO を実行すると、すぐにループが終了します。GOTO が DO ブロック内のラベルを参照する場合、制御はラベルの場所に正しく転送されますが、バッチ パーサーは FOR ループ コンテキストについて何も認識しません。コードは、ループ内にないかのように実行されます。詳細については、 (Windows バッチ) Goto within if ブロックが非常に奇妙な動作をする に対する受け入れられた回答を参照してください。
2) ラベルの位置は性能に影響を与える可能性があります。
これは、非常に大きなスクリプトを扱っていない限り、通常は問題になりません。
GOTO :label
(または)を実行するCALL :label
と、バッチ プロセッサは現在のスクリプトの場所からスキャンを開始し、最初に出現する を探し:label
ます。ラベルが見つからずにファイルの最後に到達した場合は、先頭に戻って検索を続けます。ラベルが見つからずに開始点に到達すると、エラーが発生します。そのため、非常に大きなスクリプトでは、それぞれの GOTO (または CALL) の直後にラベルが表示されるようにスクリプトを構成することで、パフォーマンスが向上する場合があります。もちろん、ラベルが多くの場所から参照されている場合、それは不可能な場合があります。
3) 実際には、同じラベルを複数の場所で安全に使用できます (お勧めしません)。
上記のポイント 2 で説明したラベル スキャン プロセスを理解したら、注意を払えばラベルを安全に再利用できます。
たとえば、次のスクリプトは正しく機能します。
@echo off
for %%A in (1 2 3 X Y Z) do (
echo %%A
if %%A equ 3 goto break
)
:break
for %%A in (A B C 8 9 10) do (
echo %%A
if %%A equ C goto break
)
:break
-- 出力 --
1
2
3
A
B
C
ラベルの再利用は機能しますが、スクリプトを解釈またはデバッグしようとする他のユーザーを混乱させる可能性があるため、お勧めできません。