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

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

Perl のハッシュを正しく理解したいと思います。かなり長い間、Perl を断続的に使用する必要がありましたが、ほとんどの場合、必要なときはテキスト処理に関連しています。

そして、ハッシュを扱うたびに混乱してしまいます。ハッシュの構文は非常に難解だと思います

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

ベストアンサー1

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

@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";

少しだけ豊富な構造で情報を表現したいとします。

  • クリーバー(姓)
    • ウォード(名)
    • ジューン(配偶者のファーストネーム)
  • フリントストーン
    • フレッド
    • ウィルマ
  • 陣地壕
    • アーチー
    • エディス

参照が登場する前は、フラットなキーバリューハッシュが最善の策でしたが、参照によって

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

内部的には、 のキーと値は%personal_infoすべてスカラーですが、値は で作成されたハッシュ参照という特別な種類のスカラーです。{}参照によって、「多次元」ハッシュをシミュレートできます。たとえば、次のようにして Wilma にアクセスできます。

$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++ のポインタに似ていますが、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サブが返されるとすぐに破棄されるコピーが取得されます。

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

おすすめ記事