为什么这样做?这是第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
Run Code Online (Sandbox Code Playgroud)
我理解如果我小心地使用%$ a和%$ b perl会知道我的意思,但是在列表中只有裸露的参考,为什么它有用?
或者它看起来像是有效的,我真的做了别的什么?
Sin*_*nür 13
没有列表上下文
$c = ($a, $b);
Run Code Online (Sandbox Code Playgroud)
相反,您所看到的是运行中的逗号运算符:
二进制","是逗号运算符.在标量上下文中,它评估其左参数,抛出该值,然后计算其右参数并返回该值.这就像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";
Run Code Online (Sandbox Code Playgroud)
首先,我使用了警告.因此,当我运行此脚本时,我收到警告:
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.
请注意,仅括号不会创建列表上下文.如果是
my @z = ($x, $y);
Run Code Online (Sandbox Code Playgroud)
它们是必要的,因为=绑定比逗号运算符更紧密.
my @z = $x, $y;
Run Code Online (Sandbox Code Playgroud)
将分配$x给$z[0]并丢弃$y(和发出一个警告),而
my @z = 1 .. 5;
Run Code Online (Sandbox Code Playgroud)
会按预期工作.
最后,如果你想分配给$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;
Run Code Online (Sandbox Code Playgroud)
哪个会输出:
$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;
Run Code Online (Sandbox Code Playgroud)
输出:
VAR1 = {
'a' => [
1,
2
],
'b' => [
0
]
};