9

根据 for last( http://perldoc.perl.org/functions/last.html ) 的 perl 手册,last不能用于跳出do {}循环,但它没有提到替代方案。我正在维护的脚本具有以下结构:

do {
    ...
    if (...) 
    {
        ...
        last;
    }
} while (...);

我很确定他想走到循环的结尾,但它实际上退出了当前的子例程,所以last如果有人可以推荐更好的方法,我需要更改或重构整个循环。

4

6 回答 6

17

将 do“循环”包装在一个裸块中(这一个循环):

{
    do {
        ...
        if (...) 
        {
            ...
            last;
        }
    } while (...);
}

这适用于最后和重做,但不适用于下一个;将裸块放在 do 块内:

do {{
    ...
    if (...) 
    {
        ...
        next;
    }
    ...
}} while (...);
于 2010-12-06T18:34:38.310 回答
10

do BLOCK while (EXPR)有趣的是 do 并不是真正的循环结构。所以,last、next 和 redo 不应该在那里使用。当发现这种情况时,去掉最后一个并调整 EXPR 以评估 false。另外,打开严格,这应该至少给你一个警告。

于 2010-12-06T18:22:56.773 回答
2

从不喜欢 Perl 中的 do/while 循环。这do不是一个真正的循环,这就是为什么last不会打破它。在我们过去的Pascal发呆中,您无法在中间退出循环,因为根据圣人 Niklaus “一个入口/一个出口” Wirth 的说法,那将是错误的。因此,我们必须创建一个退出标志。在 Perl 中,它看起来像这样:

my $endFlag = 0;
do {
    ...
    if (...) 
    {
        ...
        $endFlag = 1;
    }
} while ((...) and (not $endFlag));

现在,您可以看到 Pascal 从未流行过。

于 2010-12-06T19:03:23.113 回答
2

为什么不只使用一个while循环?

while (...) {
  ...
  if (...) {
    last;
  }
}

您可能需要稍微更改您的逻辑以适应您的测试在循环的开头而不是结尾的事实,但这应该是微不足道的。

顺便说一句,如果您使用 Delphi,您实际上可以跳出 Pascal 循环,并且 Delphi DID 流行了一段时间,直到 Microsoft 明智并推出了 .net 语言。

于 2013-01-04T19:35:14.793 回答
1

@ "http://perldoc.perl.org/functions/last.html": last 不能用于退出一个返回值的块,例如 eval {} 、 sub {} 或 do {} ,也不应该使用退出 grep() 或 map() 操作。

所以,在'while()'中使用一个布尔值并将它设置在你有'last'的地方......

于 2010-12-06T18:17:31.510 回答
0

派对迟到了——我最近一直在捣乱for(;;)。在我的基本测试中,对于条件表达式AB,你想要做什么:

do {
    last if A;
} while(B);

可以实现为:

for(;; B || last) {
    last if A;
}

有点难看,但可能不比其他解决方法更难:)。一个例子:

my $i=1; 
for(;; $i<=3 || last) { 
    print "$i ";
    ++$i;
}

输出1 2 3。如果需要,您可以组合增量:

my $i=1;
for(;; ++$i, $i<=3 || last) { 
    print "$i ";
}

(使用||是因为它的优先级高于,

于 2018-04-17T13:59:42.627 回答