考虑以下简单的代码:
%hash = ('a'=>1,'b'=>2);
print $hash{'b'};
print "\n",(\%hash)->{'b'}; #used when hashes are passed by reference
#to subroutines
正如预期的那样,输出是一对2。但我在想是否$ hash {key}是引用&的缩写。解除引用完成为(\%hash) - > {key},或者是达到相同结果的完全不同的路由。
请澄清一下。
答案 0 :(得分:1)
它们有些不同,因为与许多其他语言不同,其中所有复杂类型仅作为引用可用,Perl具有实际的普通哈希类型和单独的引用类型,可以作为任何其他类型的代理。您可以在perlguts中找到有关此内容的详细信息。
最后,这两个示例都从同一存储中提取数据,当然,第二次调用时间稍长,因为它花费时间尽职地创建对plain HV的引用,然后按照您的要求将其解除引用。您可以使用B::Concise
模块研究有关内幕的详细信息。
%hash = ('a'=>1,'b'=>2);
print $hash{'b'};
print (\%hash)->{'b'};
简明输出:
$ perl -MO=Concise deref.pl
t <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 deref.pl:1) v:{ ->3
b <2> aassign[t3] vKS ->c
- <1> ex-list lKP ->8
3 <0> pushmark s ->4
4 <$> const[PV "a"] s ->5
5 <$> const[IV 1] s ->6
6 <$> const[PV "b"] s ->7
7 <$> const[IV 2] s ->8
- <1> ex-list lK ->b
8 <0> pushmark s ->9
a <1> rv2hv[t2] lKRM*/1 ->b
9 <#> gv[*hash] s ->a
c <;> nextstate(main 1 deref.pl:2) v:{ ->d
i <@> print vK ->j
d <0> pushmark s ->e
h <2> helem sK/2 ->i
f <1> rv2hv sKR/1 ->g
e <#> gv[*hash] s ->f
g <$> const[PV "b"] s ->h
j <;> nextstate(main 1 deref.pl:3) v:{ ->k
s <2> helem vK/2 ->t
q <1> rv2hv[t7] sKR/1 ->r
p <@> print sK ->q
k <0> pushmark s ->l
o <1> refgen lK/1 ->p
- <1> ex-list lKRM ->o
l <0> pushmark sRM ->m
n <1> rv2hv[t6] lKRM/1 ->o
m <#> gv[*hash] s ->n
r <$> const[PV "b"] s ->s
deref.pl syntax OK
答案 1 :(得分:1)
但我在想是否$ hash {key}是引用&amp;的简写。解除引用完成为(\%hash) - &gt; {key},或者是达到相同结果的完全不同的路由。
不,$ hash {key}只是对%hash的简单访问,就像$ array [0]是@array的简单访问一样。但\%hash是对%hash的引用,因此需要解除引用才能访问它。语法(\%hash)->{key}
简称:
do { my $temp_ref = \%hash; $temp_ref->{key} }
但是如果你有%hash,那么$ hash {key}可以很好地工作,而无需无用的引用/解除引用。哈希和数组(通常)通过引用子例程传递,因为perl的列表展平使得很难传递多个子例程。 (一个常见的例外是实现命名参数的函数。)
有关perl中参考文献的完整说明,请参阅perldoc perreftut
和perldoc perlref
。
答案 2 :(得分:0)
Perl 5中的sigil($%@)发生了变化,因为它反映了所访问的值。
my @a = (10, 20, 30); # Whole array
print $a[1]; # Single scalar element of @a
my %h = (a=>1, b=>2); # Whole hash
print $h{a}; # Single scalar value from %h
引用所有以“$”开头的原因是它们都是标量。这有帮助吗?