4

次の単純なコードを考えてみましょう。

%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} として行われる参照と逆参照の省略形なのか、それとも同じ結果に到達するためのまったく別のルートなのかを考えていました。

説明をお願いします。

4

3 に答える 3

1

すべての複雑な型が参照としてのみ利用できる他の多くの言語とは異なり、Perl には実際の単純なハッシュ型と、他の型へのプロキシとして機能する別の参照型があるため、それらは多少異なります。これに関する詳細はperlgutsにあります。

最後に、これら 2 つの例は両方とも同じストレージからデータをプルしますが、2 番目の呼び出しは、単純な 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
于 2012-05-23T11:31:03.387 に答える
1

しかし、 $hash{key} が (\%hash)->{key} として行われる参照と逆参照の省略形なのか、それとも同じ結果に到達するためのまったく別のルートなのかを考えていました。

いいえ、$hash{key} は、$array[0] が @array の単純なアクセスになるのと同じように、%hash の単純なアクセスです。ただし、\%hash は %hash への参照であるため、アクセスするには逆参照が必要です。構文(\%hash)->{key}は次のようになります。

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

しかし、とにかく %hash がある場合、 $hash{key} は無駄な参照/逆参照なしでうまく機能します。ハッシュと配列は (一般に) 参照によってサブルーチンに渡されます。これは、perl のリストの平坦化により複数のパスを渡すことが難しくなるためです。(1 つの一般的な例外は、名前付きパラメーターを実装する関数です。)

perl での参照の完全な説明については、perldoc perreftutおよびを参照してください。perldoc perlref

于 2012-05-23T13:48:38.583 に答える
0

印章($%@)は、アクセスされている値を反映しているため、Perl5で変更されます。

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

参照がすべて「$」で始まる理由は、それらがすべてスカラーであるためです。それは役に立ちますか?

于 2012-05-23T11:16:17.823 に答える