可能重复:
What's the difference between iterating over a file with foreach or while in Perl?
在while循环中,Perl读取一行输入,将其放入 变量,并运行循环体。然后,它回去找 另一条输入线。但是在foreach循环中,行输入 运算符正在列表上下文中使用(因为foreach需要一个列表 迭代)。所以它必须先读取所有输入 循环可以开始运行。当这个差异将变得明显 输入来自您的400 MB Web服务器日志文件!一般来说 最好使用像while循环的快捷方式这样的代码来处理 尽可能一次输入一行。 Source-The Llama book
我每次都应该使用while
吗? foreach
循环可能会在什么情况下占主导地位?
答案 0 :(得分:7)
正如您所指出的,在循环开始之前,使用foreach
遍历文件会将文件丢入内存。
虽然Perl的一个信条确实是“有多种方式可以做到”,但是存在一些方法可以做一些其他方式没有实际好处的事情。 foreach
可能是循环文件的不良替代方案。如果您要逐行迭代文件,通常使用while()
。如果您要将整个文件一次性打入内存,只需一步即可完成,然后完成。
有时可能会有利于整个文件的诋毁。例如,其中之一是最小化必须打开文件的时间。通常情况下,它是为了方便处理不一致的数据或按记录模型记录的数据。 foreach()会篡改文件,但实际上并没有提供立即关闭它的好机会,因此好处就消失了。如果您的数据必须被视为一个块,那么使用foreach循环遍历该文件对您没有多大帮助。所以这个理由也消失了。最后,你得到了诋毁文件的负面消息,没有任何积极的诽谤文件。
总会有人提出一个其他人没有考虑的聪明理由。但我还没有看到它。 (通常当我说某人发布“it”之类的东西时,所以建议它绝对没有任何优点总是危险的。)让我们这样说:直到你发现使用foreach迭代一个极少的好理由之一文件,不要担心。当你确实做出这个发现时,你会知道现在是时候了。
答案 1 :(得分:6)
一般的经验法则是,如果您正在使用的东西在使用时发生变化,请使用while
:
while(my $line = <>)
while(my ($k, $v) = each %h)
但是for
或foreach
否则:
foreach my $line (@lines)
for my $k (keys %h)
for(my $i = 0; $i < $pancakes; ++$i)
对于文件,使用while
是有道理的,因为你(可能)不想将整个事物淹没到内存中(当然,除非你想要)。但是,如果您已将数据存储在内存中,那么for
/ foreach
将是迭代它的更自然的选择。
答案 2 :(得分:3)
当数据已经在内存中时,使用foreach
迭代数组的每个元素或散列的每个键。当数据尚未存储在内存中时使用while
(您甚至可能不需要将其全部保存在内存中)。
my %hash;
while (<>)
{
chomp;
my($key, $value) = split /,/;
$hash{$key} = $value;
}
foreach my $key (sort keys %hash)
{
print "$key => $hash{$key}\n";
}