goto LABEL
goto EXPR
goto &NAME

goto LABEL 形式查找标记为 LABEL 的语句,并在那里恢复执行。它不能用于退出块或提供给 sort 的子程序。它可用于进入动态作用域内的几乎任何其他位置,包括退出子程序,但通常最好使用其他一些构造,例如 lastdie。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 LABELgoto EXPR 跳转到构造中已弃用,并且会发出警告。即使如此,它也不能用于进入任何需要初始化的构造,例如子例程、foreach 循环或 given 块。一般而言,它不能用于跳转到二进制或列表运算符的参数中,但它可以用于跳转到二进制运算符的第一个参数中。(= 赋值运算符的“第一个”操作数是其右侧操作数。)它也不能用于进入被优化掉的构造中。

goto &NAME 形式与其他形式的 goto 非常不同。事实上,它根本不是通常意义上的 goto,并且没有与其他 goto 相关的污名。相反,它退出当前子例程(丢失由 local 设置的任何更改),并立即使用 @_ 的当前值调用指定名称的子例程。这由希望加载另一个子例程并假装该另一个子例程一开始就被调用的 AUTOLOAD 子例程使用(除了对 @_ 在当前子例程中的任何修改都会传播到另一个子例程。)在 goto 之后,甚至 caller 也无法知道该例程首先被调用。

NAME 不必是子例程的名称;它可以是包含代码引用的标量变量或求值为代码引用的块。