简体   繁体   English

我应该在Perl中使用哪个“for”循环?

[英]Which “for” loop should I use in Perl?

What are the arguments for using one of the for loops over the other to count through integers? 使用其中一个for循环来计算整数的参数是什么?

for my $i (0..$n) { ... }

for (my $i = 0; $i <= $n; $i++) { ... }

In your case, there isn't any difference. 在你的情况下,没有任何区别。

In other use cases, in a for-each loop you don't have control of or access to the iterator. 在其他用例中,在for-each循环中,您无法控制或访问迭代器。

Using your example syntax: 使用您的示例语法:

for my $i (0..10)
{
   print "$i";
   $i++;
}

The above actually creates a foreach loop - it's the same as saying foreach my $i (0..10) . 上面实际上创建了一个foreach循环 - 它与foreach my $i (0..10) $i is a value returned from the list , not the iterator. $i从列表返回 ,而不是迭代器。 The iterator is internal and you don't have any access to it; 迭代器是内部的,你没有任何访问权限; you can not control the flow of the loop. 你无法控制循环的流量。

The output from above will print 012345678910 . 上面的输出将打印012345678910

This: 这个:

for ( my $i = 0; $i++ ; $i <= 10)
{
    print $i;
    $i++;
}

That is an actual for loop. 这是一个实际的for循环。 You are controlling and outputting the iterator. 您正在控制并输出迭代器。 It will output: 0246810 它将输出: 0246810

In addition: 此外:

When you do for (1..$n) you are invoking the range operator vs. doing a simple comparison at the top of the loop. 当您执行for (1..$n)您将调用范围运算符,而不是在循环顶部进行简单比较。 Performance differences, however, would be immeasurable. 但是,性能差异是无法估量的。

The difference between the two styles of for loops in Perl is one of both clarity and efficiency. Perl中两种for循环风格的区别在于清晰度和效率。

When you look at for my $i (0 .. $n) {...} you can instantly see the range being used without having to mentally parse a larger expression. 当你查看for my $i (0 .. $n) {...}你可以立即看到正在使用的范围,而无需在心理上解析更大的表达式。

With for (my $i = 0; $i <= $n; $i++) {...} there is quite a bit more to look at, and more places where errors can creep in. for (my $i = 0; $i <= $n; $i++) {...}还有更多要关注的内容,以及更多可能出现错误的地方。

In addition, foreach over a range is faster than the equivalent C-style loop as shown by the following benchmark: 此外,一个范围内的foreach比等效的C风格循环更快,如下面的基准所示:

use Benchmark 'cmpthese';

for my $mag (map 10**$_, 1 .. 6) {
    print "\n$mag:\n";
    cmpthese -2 => {
        loop => sub {my $x = 0; for (my $i = 0; $i <= $mag; $i++) {$x += $i}},
        each => sub {my $x = 0; for my $i (0 .. $mag) {$x += $i}},
    };
}

which prints: 打印:

10:
         Rate loop each
loop 613877/s   --  -2%
each 625568/s   2%   --

100:
         Rate loop each
loop  79481/s   -- -24%
each 104758/s  32%   --

1000:
        Rate loop each
loop  8140/s   -- -27%
each 11220/s  38%   --

10000:
       Rate loop each
loop  832/s   -- -26%
each 1124/s  35%   --

100000:
       Rate loop each
loop 81.6/s   -- -26%
each  110/s  34%   --

1000000:
       Rate loop each
loop 6.90/s   -- -26%
each 9.27/s  34%   --

With the three-part for loop, you are able to $i += 3 and such if you want from within the loop, but with the foreach loop, you are not. 使用三部分for循环,你可以$i += 3 ,如果你想从循环内部这样做,但是使用foreach循环,你不是。 That is the difference. 这就是区别。

The off-by-one error that you originally had in the C-style loop shows that the C-style loop is more error prone, and should only be used if you actually need access to the loop counter. 您最初在C风格循环中出现的逐个错误表明C风格的循环更容易出错,并且只有在您确实需要访问循环计数器时才应该使用。 A foreach loop makes it much more difficult to make an off-by-one error. foreach循环使得逐个错误变得更加困难。

I believe that the two loop examples you posted behave identically. 我相信你发布的两个循环示例表现相同。 In both cases, $i is lexically scoped (since you use the my keyword). 在这两种情况下, $i都是词法范围的(因为你使用my关键字)。 I think the 0..$n syntax is clearer, but (surprise!) not everyone would agree with that. 我认为0..$n语法更清晰,但(惊喜!)不是每个人都同意这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM