6

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

类型 1-

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

或者

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

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

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

类型 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 文件。

是否会在每个步骤中使用 my will 完成变量关联?

4

5 回答 5

10

首先,两者最大的区别

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

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

在于范围,而不仅仅是针对速度或执行时间的优化。

在第一种情况下,$line仅在 while 循环中可见。在那之后,它超出了范围,你恢复了记忆,并且你出错的机会更少(通过使用$linelater 而不会出错。

资料来源:请参阅有关 for loops 的 perldoc

于 2013-09-23T05:55:23.873 回答
7

这是一个基准:

#!/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%      --

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

于 2013-09-23T09:06:19.383 回答
5

说:

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

或者

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

将变量的范围分别限制在$mykeyand循环中。$lineforeachwhile

你可能还想说use strict 'vars'

于 2013-09-23T05:54:36.660 回答
5

除了其他人所说的范围之外,如果您不在循环中使用词法循环迭代器,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 策略中的更多细节。

于 2013-09-23T08:48:09.567 回答
3

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

类型 1,每次循环运行时都会清除变量。

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

于 2013-09-23T06:26:53.803 回答