2012-05-23 46 views
4

的解除引用考慮以下簡單的代碼:perl的參考散列

%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}完成的引用&取消引用的縮寫形式,還是完全不同的路徑才能達到相同的結果。

請給予一些澄清。

回答

1

它們有些不同,因爲與許多其他語言不同,其中所有複雜類型僅作爲引用提供,Perl具有實際的簡單散列類型和單獨的引用類型,可以作爲任何其他類型的代理。你可以在perlguts找到關於這方面的血腥細節。

最後,這兩個例子都從相同的存儲中提取數據,當然,但第二次調用會稍微長一點,因爲它花費時間盡職地創建對純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 
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 

所有以「$」開頭的原因是它們都是標量。這有幫助嗎?

1

但我想$哈希{鍵}是否是引用&取消引用完成爲(\%哈希)的簡寫 - > {鍵} ,還是達到相同結果的完全不同的路線?

否,$ {散列關鍵}是在同樣的方式,$數組[0]將是@array的一個簡單的訪問%散列的只是一個簡單的訪問。但\%散列是對%散列的引用,因此需要解引用才能訪問它。語法(\%hash)->{key}將簡稱:

do { my $temp_ref = \%hash; $temp_ref->{key} } 

但如果你有%哈希反正$ {哈希鍵}很好地工作沒有無用的引用/取消引用。哈希和數組(通常)通過引用傳遞給子例程,因爲perl的列表扁平化使得難以通過多個其他方法。 (一個常見的例外是實現命名參數的功能。)

有關perl中引用的完整說明,請參見perldoc perreftutperldoc perlref