perl -Mstrict -wlE 'my %h; say grep 0, $h{poluted}; say keys %h'
输出
poluted
和
perl -Mstrict -wlE 'my %h; say grep 0, my @r= $h{poluted}; say keys %h'
没有输出。
我想知道为什么输出不同?
perl -Mstrict -wlE 'my %h; say grep 0, $h{poluted}; say keys %h'
输出
poluted
和
perl -Mstrict -wlE 'my %h; say grep 0, my @r= $h{poluted}; say keys %h'
没有输出。
我想知道为什么输出不同?
在 Perl 的循环结构map
和grep
中for
,$_
变量被别名为每个当前项。虽然$_
可能是只读的,但它始终表示有效的标量值。
例如,以下代码死亡:
$_ = 1 for 1, 2, 3; # constants are read-only
但这有效:
my @nums = (1, 2, 3);
$_ = 1 for @nums; # @nums isn't read-only
请注意,分配执行复制,但别名将名称与现有标量相关联。
undef
值Perl 有两种undef
:
标量可以设置为表示undef
。例如:
my $foo; # is this kind of undef
$foo = 1; # isn't undef any more
一个特殊的全局唯一标量,表示只读undef
值,例如,当您在右值上下文中访问未初始化的数组索引时返回。在 Perl API 中,这是&PL_sv_undef
. 您可以获得对该值的引用,例如\undef
,并且可以为它取一个变量的别名。
在内部,使用hv_fetch
or获取哈希条目hv_fetch_ent
。作为参数,两者都采用散列、密钥和标志,告诉它们访问是否是只读的。
如果这是一个只读访问并且该元素不存在,则将返回一个空指针,它undef
在 Perl 空间中显示为该值。此undef
值未连接到散列。因此,not exists $hash{foo}
暗示not defined $hash{foo}
。
但如果它不是只读的并且该元素不存在,则会创建一个新条目,然后将其返回。但是,此条目最初是undef
,直到通过赋值将其设置为另一个值。
grep 0, $h{polluted}
循环构造的参数列表别名为$_
. 如果列表中的表达式是常量或子例程,那么就不会发生什么了不起的事情。但是当它们是变量访问时,这意味着读写访问。
因此,为了获得 的值$h{polluted}
,Perl 显然是以读写模式进行访问。如果我们查看这个表达式的操作码,我们确实看到了:
3 <0> pushmark s
4 <#> gv[*h] s
5 <1> rv2hv sKR/1
6 <$> const[PV "polluted"] s/BARE
7 <2> helem sKM/2 # <-- hash element access, "M" flag is set!
8 <@> grepstart K
9 <|> grepwhile(other->a)[t2] vK
a <$> const[IV 0] s
goto 9
M
代表,MOD
表示左值/读写访问。
在for
-loops 中,$_
成为当前元素的别名可能非常有用。在map
和grep
中,这是一种避免复制整个标量的性能技巧。别名要便宜得多,因为这仅意味着单个指针的副本。