2009-11-30 23 views
50

私はPerlでハッシュを正しく理解したいと思います。私はかなりの間、断続的にPerlを使用しなければなりませんでした。ほとんどの場合、私はそれを行う必要があるときには、ほとんどがテキスト処理に関連しています。Perlでのハッシュとハッシュリファレンスの違いは何ですか?

いつも、私はハッシュに対処しなければならない、それは台無しになる。私は構文がハッシュのために非常に潜在的であることがわかります

ハッシュとハッシュリファレンス、それらの相違点、必要な時などの良い説明は非常に高く評価されます。

+35

_ *あなたがアップルを手渡す* _ハッシュのふりをする。 _ *あなたは冷蔵庫のリンゴに書かれた指示を手渡します。* _はハッシュリファレンスです。 –

+2

ハッシュに関する_Learning Perl_の章を参照してください。 –

+0

@〜クワック:私はあなたが正しくあなたにアップアップすることができるように、コメントではなく答えであったことを願っています。 –

答えて

78

単純なハッシュは配列に近いです。それらの初期化も同様に見えます。最初の配列:

@last_name = (
    "Ward", "Cleaver", 
    "Fred", "Flintstone", 
    "Archie", "Bunker" 
); 

今度は、ハッシュ(別名連想配列)と同じ情報を表現してみましょう:

%last_name = (
    "Ward", "Cleaver", 
    "Fred", "Flintstone", 
    "Archie", "Bunker" 
); 

彼らは同じ名前を持っていますが、配列@last_nameとハッシュ%last_nameは完全に独立しています。配列で

、我々はアーチーの姓を知りたい場合は、我々は線形検索を実行する必要があります。ハッシュで

my $lname; 
for (my $i = 0; $i < @last_name; $i += 2) { 
    $lname = $last_name[$i+1] if $last_name[$i] eq "Archie"; 
} 
print "Archie $lname\n"; 

を、それははるかに直接的な構文的です:

print "Archie $last_name{Archie}\n"; 

セイわずかにより豊かな構造だけで情報を表現したい:

  • クリーパー(姓)
    • 区(名)
    • 6月(配偶者の最初の名前)
      • フレッド
      • ウィルマ
    • バンカー
    • フリントストーンアーチー
    • エディス

の参照が登場する前に、フラットキーと値のハッシュは、我々は何ができる最高の約あったが、参照は、キーと値の、内部

my %personal_info = (
    "Cleaver", { 
     "FIRST", "Ward", 
     "SPOUSE", "June", 
    }, 
    "Flintstone", { 
     "FIRST", "Fred", 
     "SPOUSE", "Wilma", 
    }, 
    "Bunker", { 
     "FIRST", "Archie", 
     "SPOUSE", "Edith", 
    }, 
); 

を許可%personal_infoはすべてスカラーですが、値は{}で作成された特殊な種類のスカラー:ハッシュ参照です。これらの参照により、「多次元」のハッシュをシミュレートすることができます。たとえば、私たちは、Perlは私たちが添字間の矢印を省略することができます

$personal_info{Flintstone}->{SPOUSE} 

注意を経由してウィルマに取得することができますので、上記のあなたが知りたい場合は入力の多くはい

$personal_info{Flintstone}{SPOUSE} 

に相当しますあなたはカーソルの一種のような基準をつかむかもしれないので、フレッドの詳細は、:

$fred = $personal_info{Flintstone}; 
print "Fred's wife is $fred->{SPOUSE}\n"; 

上記のスニペットで$fredはハッシュリファレンスなので、矢印が必要です。あなたはそれを残したが、賢明にエラーこれらの種類をキャッチ助けるためにuse strictを有効にした場合、コンパイラは文句を言うだろう:

Global symbol "%fred" requires explicit package name at ... 

Perlの参照は、CおよびC++でのポインタに似ていますが、nullになることはありません。 CとC++のポインタは逆参照を必要とするため、Perlで参照を行います。

CおよびC++関数のパラメータには、値渡しのセマンティクスがあります。コピーは単なるコピーであるため、変更は呼び出し元に戻りません。変更を確認したい場合は、ポインタを渡す必要があります。あなたはPerlで参照してこの効果を得ることができます。

sub add_barney { 
    my($personal_info) = @_; 

    $personal_info->{Rubble} = { 
     FIRST => "Barney", 
     SPOUSE => "Betty", 
    }; 
} 

add_barney \%personal_info; 

をバックスラッシュがなければ、add_barneyはサブリターンとすぐに捨てられていますコピーを得ているでしょう。

上記の「脂肪カンマ」(=>)の使用にも注意してください。その文字列を左に自動で付けることで、ハッシュの初期化の文法的なノイズが少なくなります。

+0

です。7年後にCとC++はポインタを使わずに参照渡しを許可することに注意してください。 'void f(DataType&arg)'は参照によって 'arg'を渡し、アクセスや変更を行う際に逆参照を必要としません。 –

+0

@JimVこれは、エイリアスの「並べ替え」である、 '&'で宣言された_reference_を渡すときです。セマンティクスは値渡しです。 – zdim

+0

素晴らしい投稿:)。コメント - おそらく '@ _'が引数のエイリアスになるので、注意が必要です。したがって、ハッシュキー以外のサブキーから変更することはできますか? – zdim

10

ハッシュはPerlの基本データ型です。 キーを使用してコンテンツにアクセスします。

ハッシュリファレンスは、ハッシュへの参照の略で、 です。参考文献は スカラーです。これは単純な値です。実質的に ハッシュ自体へのポインタである を含むスカラー値である です。

リンク:difference between hash and hash ref in perl - Ubuntu Forums

差は削除するための構文でもあります。 Cのように、perlがハッシュのために、このように動作します:

delete $hash{$key}; 

とハッシュリファレンスのため

delete $hash_ref->{$key}; 

Perl Hash Howtoはハッシュリファレンス

でハッシュ対ハッシュを理解するための素晴らしいリソースである他にもありますリンクhere that has more information on perl and references

6

perldoc perlreftutを参照してください。これは、ご使用のコンピュータのコマンドラインからもアクセスできます。

リファレンスは、配列全体またはハッシュ全体(またはその他のもの)を参照するスカラー値です。名前はすでによく知っている参考資料の1つです。米国大統領のことを考えてみましょう。血液や骨の厄介で不都合なバッグです。しかし、彼について話をするか、コンピュータプログラムで彼を代弁するには、簡単で便利なスカラー文字列 "Barack Obama"だけが必要です。

Perlでの参照は、配列やハッシュの名前に似ています。彼らはPerlのプライベートな内部名なので、明白であると確信できます。 「バラク・オバマ(Barack Obama)」とは異なり、参考文献は1つのことだけを指し、あなたはいつもそれが何を指しているか知っています。配列への参照がある場合は、配列全体を復元することができます。ハッシュへの参照がある場合は、ハッシュ全体を復元できます。しかし、リファレンスはまだ簡単でコンパクトなスカラー値です。

+0

@ mjp66答えの重要な部分は、OPコンピュータに 'perl'と一緒にインストールされた' perldoc perlreftut'を使うことです。これはOPが使用している* perl *の特定のバージョンのための最も正確な文書です。リンクは礼儀としてのみ含まれています。その意味では、PerlのドキュメンテーションURLはまったく同じようなものです。リンクの内容は変わるかもしれませんが、リンクは常に "Perl References Tutorial"を指しています。すべてのリンクが等しく作成されるわけではありません。 FYI。 –

15

次は、ハッシュとハッシュリファレンスを使用する方法を示しています

my %hash = (
    toy => 'aeroplane', 
    colour => 'blue', 
); 
print "I have an ", $hash{toy}, " which is coloured ", $hash{colour}, "\n"; 

my $hashref = \%hash; 
print "I have an ", $hashref->{toy}, " which is coloured ", $hashref->{colour}, "\n"; 

perldoc perldscを参照してください。

+8

個人的には、ハッシュを記述するために '%hash 'という用語を見るのは混乱していました。あなたの '%hash 'を'%favorite'と再ラベル付けして、自宅を動かすのは良い考えです。 printステートメントは 'print 'のようなものになります。私のお気に入りのおもちゃは$ favorite {toy}"; ' – Zaid

関連する問題