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 my $i (0..$n) { ... }
for (my $i = 0; $i <= $n; $i开发者_StackOverflow++) { ... }
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.
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)
. $i
is a value returned from the list, not the iterator. 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
.
This:
for ( my $i = 0; $i++ ; $i <= 10)
{
print $i;
$i++;
}
That is an actual for
loop. You are controlling and outputting the iterator. It will output:
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. Performance differences, however, would be immeasurable.
The difference between the two styles of for
loops in Perl is one of both clarity and efficiency.
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.
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.
In addition, foreach
over a range is faster than the equivalent C-style loop as shown by the following benchmark:
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. 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. A foreach loop makes it much more difficult to make an off-by-one error.
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 think the 0..$n
syntax is clearer, but (surprise!) not everyone would agree with that.
精彩评论