goto LABEL
形式查找标记为 LABEL 的语句,并在那里恢复执行。它不能用于退出块或提供给 sort
的子程序。它可用于进入动态作用域内的几乎任何其他位置,包括退出子程序,但通常最好使用其他一些构造,例如 last
或 die
。Perl 的作者从未觉得有必要使用这种形式的 goto
(在 Perl 中,即 C 是另一回事)。(区别在于 C 不提供命名循环与循环控制的组合。Perl 提供,这取代了其他语言中 goto
的大多数结构化用法。)
goto EXPR
形式期望将 EXPR
求值到代码引用或标签名。如果它求值到代码引用,它将被处理为 goto &NAME
,如下所示。这对于通过 goto __SUB__
实现尾递归特别有用。
如果表达式求值到标签名,则其作用域将动态解析。这允许根据 FORTRAN 进行计算的 goto
,但如果您针对可维护性进行优化,则不一定推荐
goto ("FOO", "BAR", "GLARCH")[$i];
如本示例所示,goto EXPR
不受“看起来像函数”规则的约束。它后面的一对括号(不一定)界定其参数。goto("NE")."XT"
等同于 goto NEXT
。此外,与大多数命名运算符不同,它具有与赋值相同的优先级。
使用 goto LABEL
或 goto EXPR
跳转到构造中已弃用,并且会发出警告。即使如此,它也不能用于进入任何需要初始化的构造,例如子例程、foreach
循环或 given
块。一般而言,它不能用于跳转到二进制或列表运算符的参数中,但它可以用于跳转到二进制运算符的第一个参数中。(=
赋值运算符的“第一个”操作数是其右侧操作数。)它也不能用于进入被优化掉的构造中。
goto &NAME
形式与其他形式的 goto
非常不同。事实上,它根本不是通常意义上的 goto,并且没有与其他 goto 相关的污名。相反,它退出当前子例程(丢失由 local
设置的任何更改),并立即使用 @_
的当前值调用指定名称的子例程。这由希望加载另一个子例程并假装该另一个子例程一开始就被调用的 AUTOLOAD
子例程使用(除了对 @_
在当前子例程中的任何修改都会传播到另一个子例程。)在 goto
之后,甚至 caller
也无法知道该例程首先被调用。
NAME 不必是子例程的名称;它可以是包含代码引用的标量变量或求值为代码引用的块。