好的,我有以下代码:
use strict;
my @ar = (1, 2, 3);
foreach my $a (@ar)
{
$a = $a + 1;
}
print join ", ", @ar;
Run Code Online (Sandbox Code Playgroud)
和输出?
2,3,4
有没有搞错?为什么这样做?这总是会发生吗?是$ a不是一个真正的局部变量?他们在想什么?
Ano*_*on. 25
Perl有很多这些几乎奇怪的语法事物,它们大大简化了常见任务(比如迭代列表并以某种方式更改内容),但是如果你不了解它们就可以绊倒你.
$a别名为数组中的值 - 这允许您修改循环内的数组.如果您不想这样做,请不要修改$a.
Sin*_*nür 22
如果LIST的任何元素是左值,您可以通过修改循环内的VAR来修改它.相反,如果LIST的任何元素不是左值,则任何修改该元素的尝试都将失败.换句话说,foreach循环索引变量是您循环的列表中每个项的隐式别名.
尽管我发现有多少人在遇到他们不理解的行为时拒绝检查文档,但没有什么奇怪或奇怪的记录语言功能.
正如其他人所说,这是记录在案的。
我的理解是@_,for、map和的混叠行为grep提供了速度和内存优化,并为创意提供了有趣的可能性。发生的事情本质上是构造块的传递引用调用。这样可以避免不必要的数据复制,从而节省时间和内存。
use strict;
use warnings;
use List::MoreUtils qw(apply);
my @array = qw( cat dog horse kanagaroo );
foo(@array);
print join "\n", '', 'foo()', @array;
my @mapped = map { s/oo/ee/g } @array;
print join "\n", '', 'map-array', @array;
print join "\n", '', 'map-mapped', @mapped;
my @applied = apply { s/fee//g } @array;
print join "\n", '', 'apply-array', @array;
print join "\n", '', 'apply-applied', @applied;
sub foo {
$_ .= 'foo' for @_;
}
Run Code Online (Sandbox Code Playgroud)
注意List::MoreUtils apply函数的使用。它的工作原理类似于map但复制主题变量,而不是使用引用。如果你讨厌写这样的代码:
my @foo = map { my $f = $_; $f =~ s/foo/bar/ } @bar;
Run Code Online (Sandbox Code Playgroud)
你会喜欢的apply,这使它变成:
my @foo = apply { s/foo/bar/ } @bar;
Run Code Online (Sandbox Code Playgroud)
需要注意的事情:如果您将只读值传递到修改其输入值的这些构造之一中,您将收到“尝试修改只读值”错误。
perl -e '$_++ for "o"'
Run Code Online (Sandbox Code Playgroud)