为什么这样做?这是第2行
DB<1> $a = {'a'=>1}; $b = {'a'=>2, 'b'=>0};
DB<2> $c = ($a, $b);
DB<3> print $c;
HASH(0x8743e68)
DB<4> print $c->{a},$c->{b};
20
我理解如果我小心地使用%$ a和%$ b perl会知道我的意思,但是在列表中只有裸露的参考,为什么会有效?
或许它看起来像是有效的,我真的做了别的什么?
答案 0 :(得分:13)
中没有列表上下文
$c = ($a, $b);
相反,您所看到的是行动中的comma operator:
二进制“,”是逗号运算符。在标量上下文中,它评估其左参数,抛出该值,然后计算其右参数并返回该值。这就像C的逗号运算符一样。
要更清楚地看到这一点,请查看:
#!/usr/bin/perl
use strict; use warnings;
my $x = {a => 1};
my $y = {a => 2, b => 0};
my $z = ($x, $y);
print "\$x = $x\t\$y = $y\t\$z = $z\n";
my @z = ($x, $y);
print "@z\n";
首先,我使用warnings。因此,当我运行此脚本时,我收到警告:
Useless use of private variable in void context at C:\Temp\t.pl line 7.
始终启用警告。
现在,输出显示正在发生的事情:
$x = HASH(0x39cbc) $y = HASH(0x39dac) $z = HASH(0x39dac) HASH(0x39cbc) HASH(0x39dac)
显然,$z
引用与$y
相同的匿名哈希。没有复制值。
并且$z[0]
引用与$x
相同的匿名哈希,而$z[1]
引用与$y
和$z
相同的匿名哈希。< / p>
请注意,仅括号不会创建列表上下文。在
的情况下my @z = ($x, $y);
它们是必要的,因为=
比逗号运算符绑定得更紧密。
my @z = $x, $y;
会将$x
分配给$z[0]
并弃掉$y
(并发出警告),而
my @z = 1 .. 5;
会按预期工作。
最后,如果您想要为$z
分配一个新的匿名哈希,其中包含$x
和$y
指向的匿名哈希的副本,您可以
#!/usr/bin/perl
use strict; use warnings;
use Data::Dumper;
my $x = {a => 1};
my $y = {a => 2, b => 0};
my $z = { %$x, %$y };
print Dumper $z;
将输出:
$VAR1 = { 'a' => 2, 'b' => 0 };
因为根据定义,散列键是唯一的。如果要保留与两个哈希的键关联的所有值,则需要执行稍微复杂的操作(并使用匿名arrayrefs作为“union”哈希中的值):
#!/usr/bin/perl
use strict; use warnings;
use Data::Dumper;
my $x = {a => 1};
my $y = {a => 2, b => 0};
my $z;
push @{ $z->{$_} }, $x->{$_} for keys %$x;
push @{ $z->{$_} }, $y->{$_} for keys %$y;
print Dumper $z;
输出:
VAR1 = { 'a' => [ 1, 2 ], 'b' => [ 0 ] };