Perl - next和redo的区别

5

当我执行程序时,两种情况都会产生相同的结果。请解释“next”和“redo”的区别。


http://perldoc.perl.org/functions/continue.html - serenesat
1
@AruneshSingh - 请不要发布盗版书的链接。这会让 StackOverflow 面临侵权诉讼的风险。请删除你的评论。 - Dave Cross
3
@Dave Cross提到的"你让StackOverflow面临被起诉侵犯版权的风险"是错误的。他并没有说SO有罪于其他人的行为,而是如果有DMCA侵权申请,SO将会接受请求移除链接。他不应该发布链接的原因有很多,但这不是其中之一。 - ikegami
好的。说得对。它已经被移除了。 - Dave Cross
4个回答

13
for (1 .. 9) {
    next if $_ % 2;
    print;
}

打印出"2468",因为每当$_是奇数时,next跳出循环并继续下一个数字。

for (1 .. 9) {
    redo if $_ % 2;
    print;
}

由于1是奇数,因此循环永远运行且不打印任何内容,所以redo会跳回循环体的开头而不会推进循环,因此$_保持为1,从未发生任何事情。

  • next将在foreach循环中前进到下一项;redo不会。
  • next将运行C风格for循环的增量(中间)语句;redo不会。
  • next将重新检查while循环或C风格for循环中的条件;redo不会。
  • next将退出裸循环({...});redo将重新开始循环。
  • next将运行continue块;redo不会。

从语义上讲,next完成当前迭代,然后执行发生的任何事情之后redo再次运行当前迭代的所有代码next就像跳到块的底部(实际上,如果您在不是循环的块中使用它,它将直接跳到结尾),而redo就像跳到块的顶部(实际上,您可以使用redo来创建一个循环...{print"Hello";redo}相当于while (1){print"Hello"}


关于我的编辑:哦,你提到了它,但是为什么只在你的回答后面?不太确定原因。您可以根据需要进行调整。 - ikegami

13

redonextlast在Perl的循环块中使用。通常您会在forwhile块中看到它们,但如果需要,您也可以在裸块中使用它们。

关键区别是:

  • redo跳转到块的开头——打开大括号{
  • next跳转到块的结尾——闭合大括号}
  • last完全跳出块

nextlast仅对whilefor循环的块(以及具有continue部分的块)不同。

因此,您可以编写以下类型的循环:

my $n;
{
    ++$n;
    print $n, "\n";
    redo if $n < 10;
}

将会打印出从1到10的数字。


3

Next-程序执行继续进行下一次循环迭代。它就像C语言中的continue操作符。如果满足某些条件,可以使用Next关键字跳过余下的循环代码。

Redo-它使程序执行回到当前循环的顶部,而不测试任何条件表达式或前进到下一次迭代。

例如,

在Next的情况下

foreach (split){
    next;   ## next comes here ##
            # statements are skipped
}

如果需要重做

    LOOPLABEL:
        {
           $count++;
           redo LOOPLABEL if ($count < 3);
           #Does not advance to the next iteration        
        }

主要区别在于next会通过重新评估条件来推进到下一个迭代,而redo将从循环中最上面的语句重新执行当前迭代。

1
如果您能提供一些关于“next将进入下一个迭代,但redo将重复当前迭代”的示例或更多解释,那将更有帮助。 - serenesat

3

下一个:
下一个 关键字可以让您跳过语句块的其余部分并开始下一次迭代。此行为的一个用途是选择特定数组元素进行处理并忽略其余元素。

例如:

my @array = (0..9);
print "@array\n";
for (my $index = 0; $index < @array; $index++)
{
    if ($index == 3 || $index == 5)
    {
        next;
    }
    $array[$index] = "*";
}
print "@array\n";

以上示例将所有数组元素更改为星号,但第三个和第五个除外。无论其先前的值是什么。"下一个"关键字强制Perl跳过赋值语句并直接进入递增/递减表达式。您还可以在嵌套循环中使用"下一个"关键字。
重新做:
"redo"关键字会导致Perl重新启动当前语句块。在重新启动块之前,不会评估增量/减量表达式或条件表达式。通常在从程序外部获取输入(从键盘或文件)时使用此关键字。重要的是,使导致"redo"语句执行的条件可以更改,以避免出现无限循环。
例如:
{   #start a statement block 
    print "What is your name?\n";
    my $name = <STDIN>;
    chop($name);

    if (! length($name))
    {
        print "Zero length input. Please try again\n";
        redo;
    }

    print "Thank you, " . $name, "\n";
}

值得注意的是,在redo示例中的语句块像一个单次循环结构。

你的 redo 示例不起作用,因为它不在一个块内。 - dgw
1
@dgw,示例中第一行和最后一行的大括号形成了一个“裸块”——一个只执行一次的循环,除非被控制关键字修改。这就是redo操作的循环。 - LeoNerd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接