在Perl中使用我的with循环是否很好?

时间:2013-09-23 05:49:20

标签: perl

我在许多标准书籍中看到了许多代码,其中我的循环使用如下。

TYPE 1 -

foreach my $mykey ( keys %myhash) {
......
}

while(my $line = <$filehandle> ) {
.....
}

这里我们为散列的每个键或每一行声明变量。这是一个好主意吗?

在C / C ++ / Java中,我们先用变量声明然后再使用它。因此,如果我遵循该政策,则上述代码应如下所示。

TYPE 2 -

my $mykey;
foreach $mykey (keys %myhash) {
....
}

my $line;
while($line = <$filehandle> ) {
....
}

它将加速代码执行(我认为),因为根据上下文,我们决定可以对变量应用什么类型的操作以及它的行为。

但是我在Perl中看到了TYPE 1代码。所以我想我错过了一些perl概念。有人请点亮它。

如果您要说它已经声明/关联到范围一次然后增加,那么请提供一些文档。我无法在任何地方得到它。我理解变量的范围在两种情况下都是不同的。

@ http://perldoc.perl.org/perlsub.html#Private-Variables-via-my%28%29-- my运算符声明列出的变量在词法上限制在封闭块,条件(if / unless / elsif / else),循环(for / foreach / while / until / continue),子例程,eval或do / require / use 'd file。

使用my的变量关联将在每一步完成吗?

5 个答案:

答案 0 :(得分:9)

首先,

之间的最大区别
while(my $line = <$filehandle> ) {
.....
}

my $line 
while($line = <$filehandle> ) {
.....
}

位于范围,远远超过速度或执行时间的优化。

在第一种情况下,$line仅在while循环中可见。在此之后,它会超出范围,您可以恢复记忆,并且错误的机会也会减少(稍后使用$line并且不会出错。

来源:见perldoc about for loops

答案 1 :(得分:6)

这是一个基准:

#!/usr/bin/perl 
use strict;
use warnings;
use Benchmark qw(:all);

my @list = ('abc')x1_000_000;

my $count = -2;
cmpthese($count, {
    'inside' => sub {
        for my $elem(@list) { $elem = '' }
    },
    'outside' => sub {
        my $elem;
        for $elem(@list) { $elem = '' }
    },
});

<强>结果:

          Rate outside  inside
outside 14.3/s      --      0%
inside  14.3/s      0%      --

如您所见,速度方面没有差异。

答案 2 :(得分:4)

话说:

foreach my $mykey ( keys %myhash) {
  ...
}

while(my $line = <$filehandle> ) {
  ...
}

将变量$mykey$line的范围分别限制在foreachwhile循环中。

您可能还想说use strict 'vars'

答案 3 :(得分:4)

除了其他人对范围所说的内容之外,如果你在for循环中没有使用词法循环迭代器,你可能会遇到如下代码:

my $i;
for $i (1..10) {
    last if check_something($i);
}
print $i;

这看起来会在1到10之间打印一些值,具体取决于check_something中的逻辑。实际上,它总是会打印undef,因为它的解释更像是:

my $i;
{
    local $i;
    for $i (1..10) {
        last if check_something($i);
    }
}
print $i;

Perl::Critic RequireLexicalLoopIterators policy中的更多细节。

答案 4 :(得分:3)

我认为速度在这两种方法中都不是问题,因为它最小化(如果它不运行一百万次,即使这样也不会太多)。

类型1,将始终在每次循环运行时清除变量。

类型2,它不会在每次运行时发生。