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

vir*_*rus 6 perl

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

TYPE 1-

foreach my $mykey ( keys %myhash) {
......
}
Run Code Online (Sandbox Code Playgroud)

要么

while(my $line = <$filehandle> ) {
.....
}
Run Code Online (Sandbox Code Playgroud)

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

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

TYPE 2-

my $mykey;
foreach $mykey (keys %myhash) {
....
}
Run Code Online (Sandbox Code Playgroud)

要么

my $line;
while($line = <$filehandle> ) {
....
}
Run Code Online (Sandbox Code Playgroud)

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

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

如果你会说,这是声明/关联范围一次,然后加才请提供一些文档.我无法在任何地方得到它.我理解变量的范围在两种情况下都是不同的.

@ http://perldoc.perl.org/perlsub.html#Private-Variables-via-my%28%29-- 我的操作声明中列出的变量是词法仅限于封闭块,条件(如果/除非/ ELSIF /人),循环(用于/的foreach /时/直到/继续),子程序,EVAL,或者说/需要/ use'd文件.

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

Kon*_*rak 10

首先,最大的区别

while(my $line = <$filehandle> ) {
.....
}
Run Code Online (Sandbox Code Playgroud)

my $line 
while($line = <$filehandle> ) {
.....
}
Run Code Online (Sandbox Code Playgroud)

在于范围,不仅仅是速度或执行时间的优化.

在第一种情况下,$line仅在while循环中可见.在那之后,它超出了范围,你恢复了记忆,并且你犯错的可能性更小(通过使用$line以后而不会出现错误.

来源:请参阅此perldoc有关for循环.


Tot*_*oto 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 = '' }
    },
});
Run Code Online (Sandbox Code Playgroud)

结果:

          Rate outside  inside
outside 14.3/s      --      0%
inside  14.3/s      0%      --
Run Code Online (Sandbox Code Playgroud)

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


dev*_*ull 5

说:

foreach my $mykey ( keys %myhash) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

要么

while(my $line = <$filehandle> ) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

地限制变量的范围$mykey$lineforeachwhile分别循环。

您可能还想说use strict 'vars'


Rob*_*arl 5

除了其他人关于范围的说法之外,如果您在for循环中不使用词法循环迭代器,则可能会遇到类似以下的代码:

my $i;
for $i (1..10) {
    last if check_something($i);
}
print $i;
Run Code Online (Sandbox Code Playgroud)

看起来它将打印介于1到10之间的某个值,具体取决于中的逻辑check_something。实际上,它将始终打印,undef因为它的解释更像是:

my $i;
{
    local $i;
    for $i (1..10) {
        last if check_something($i);
    }
}
print $i;
Run Code Online (Sandbox Code Playgroud)

Perl :: Critic RequireLexicalLoopIterators策略中有更多详细信息。