Windows 批处理脚本中的 GOTO 通常可以安全使用,有时是必要的。但是有三个非直观的设计特征值得注意:
1) 不要 GOTO 放置在带括号的代码块中的标签
您可以 GOTO 放置在带括号的块中的标签,但它可能不会给您想要的结果。例如, FOR 循环 DO 块中的 GOTO 将立即终止循环。如果 GOTO 引用 DO 块中的标签,则控制正确地转移到标签位置,但批处理解析器现在对 FOR 循环上下文一无所知。代码将像不在循环内一样执行。有关更多信息,请参阅if 块行为非常奇怪的(Windows 批处理)Goto的公认答案。
2) 标签的位置会影响性能。
除非您正在处理一个非常大的脚本,否则这通常不是问题。
执行GOTO :label
(or 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
尽管重用标签有效,但这不是一个好的做法,因为它可能会使任何试图解释或调试脚本的人感到困惑。