所以,我从来不知道这一点,我希望得到一些澄清。我知道你是否
foreach (@list){
如果在该循环中更改$ _,则会影响实际数据。但是,我不知道如果你做了
foreach my $var1 (@list){
如果您在循环中更改了$ var1,它将更改实际数据。 : - /那么,有没有办法循环@list但保持变量是只读副本,或者如果更改的副本不会更改@list中的值?
答案 0 :(得分:10)
$var
依次为每个项目设置别名。
请参阅http://perldoc.perl.org/perlsyn.html#Foreach-Loops
如果LIST的任何元素是左值,您可以通过修改循环内的VAR来修改它。 相反,如果LIST的任何元素不是左值,则任何修改该元素的尝试 将失败。换句话说,foreach循环索引变量是每个的隐式别名 您正在循环的列表中的项目。
答案 1 :(得分:9)
最简单的方法就是复制它:
foreach my $var1 (@list) {
my $var1_scratch = $var1;
或
foreach my $var1 ( map $_, @list ) {
但是如果$ var1是一个引用,$ var1_scratch将是对同一个东西的引用。 为了非常安全,你必须使用像Storable :: dclone这样的东西来做深层复制:
foreach my $var1 ( @{ Storable::dclone( \@list ) } ) {
}
(未测试)。然后你应该能够安全地改变$ var1。但如果这样做可能会很昂贵 @list是一个很大的数据结构。
答案 2 :(得分:4)
这是别名,不是参考。如果您想创建自己的别名(在for之外),可以使用Data::Alias。
答案 3 :(得分:2)
这些循环之间的唯一区别是:
foreach (@array) { ... }
foreach my $var (@array) { ... }
是循环变量。别名是foreach
的函数,而不是隐式变量$_
。请注意,这是别名(同一事物的另一个名称),而不是引用(指向事物的指针)。
在简单(和常见)的情况下,您可以通过复制来破坏别名:
foreach my $var (@array) {
my $copy = $var;
# do something that changes $copy
}
这适用于普通的标量值。对于参考(或对象),您需要使用Storable或Clone制作深层副本,这可能很昂贵。绑定变量也存在问题,perlsyn建议完全避免这种情况。
答案 4 :(得分:1)
我不知道如何在foreach语句本身中强制变量为by-value而不是by-reference。您可以复制$_
的值。
#!/usr/perl/bin
use warnings;
use strict;
use Data::Dumper;
my @data = (1, 2, 3, 4);
print "Before:\n", Dumper(\@data), "\n\n\n";
foreach (@data) {
my $v = $_;
$v++;
}
print "After:\n", Dumper(\@data), "\n\n\n";
__END__
答案 5 :(得分:0)
在for语句中复制@list:
foreach my $var1 (() = @list) {
# modify $var without modifying @list here
}