web-dev-qa-db-ja.com

Perlのハッシュとハッシュ参照の違いは何ですか?

Perlのハッシュを適切に理解したいと思います。私はかなり長い間Perlを断続的に使用しなければなりませんでしたが、ほとんどの場合、Perlはテキスト処理に関連しています。

そして、毎回、ハッシュを処理する必要があり、それはめちゃくちゃになります。ハッシュの構文は非常にわかりにくい

ハッシュとハッシュ参照、それらの違い、必要な場合などについての良い説明をいただければ幸いです。

61
user855

単純なハッシュは配列に近いものです。初期化も似ています。最初に配列:

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

次に、同じ情報をハッシュ(別名連想配列)で表現しましょう。

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

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

配列を使用して、Archieの姓を知りたい場合は、線形検索を実行する必要があります。

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のキーと値はすべてスカラーですが、値は特別な種類のスカラーです:{}で作成されたハッシュ参照。この参照により、「多次元」ハッシュをシミュレートできます。たとえば、次の方法でウィルマに到着できます

$personal_info{Flintstone}->{SPOUSE}

Perlでは、添え字間の矢印を省略することができるため、上記は次と同等です。

$personal_info{Flintstone}{SPOUSE}

Fredの詳細を知りたい場合は、多くの入力が必要なので、参照をカーソルのようなものとして取得できます。

$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++のポインターに似ていますが、決してヌルになることはありません。 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は、subが戻るとすぐに破棄されるコピーを取得することになります。

上記の「ファットコンマ」(=>)の使用にも注意してください。左側の文字列を自動引用し、ハッシュの初期化の構文上のノイズを少なくします。

87
Greg Bacon

以下は、ハッシュとハッシュ参照を使用する方法を示しています。

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 も参照してください。

16

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

ハッシュ参照は、ハッシュへの参照の略語です。参照はスカラー、つまり単純な値です。これは、実際のハッシュ自体へのポインターを本質的に含むスカラー値です。

リンク: Perlでのハッシュとハッシュrefの違い-Ubuntuフォーラム

違いは、削除の構文にもあります。 Cと同様に、Perlはハッシュに対して次のように機能します。

delete $hash{$key};

およびハッシュ参照用

delete $hash_ref->{$key};

Perl Hash Howto は、ハッシュ参照とハッシュ対ハッシュを理解するための優れたリソースです

別のリンクもあります ここにはPerlと参照に関する詳細情報があります

10
user195488

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

参照は、配列全体またはハッシュ全体(または他のほぼすべて)を参照するスカラー値です。名前は、すでによく知っているリファレンスの一種です。米国の大統領を考えてみてください:厄介で不便な血液と骨の袋。しかし、彼について話すため、またはコンピュータープログラムで彼を表すために必要なのは、簡単で便利なスカラー文字列 "Barack Obama"だけです。

Perlでの参照は、配列とハッシュの名前に似ています。これらはPerlのプライベートな内部名であるため、明確であることを確認できます。 「バラクオバマ」とは異なり、参照は1つのものだけを参照し、それが何を参照するかを常に知っています。アレイへの参照がある場合、そこからアレイ全体を回復できます。ハッシュへの参照がある場合、ハッシュ全体を回復できます。しかし、参照は依然として簡単でコンパクトなスカラー値です。

7
Sinan Ünür