Perl中的哈希和哈希引用之间有什么区别?

收藏

我想正确地理解Perl中的哈希值。我不得不断断续续地使用Perl了很长时间,并且大部分时候需要使用它,这主要与文本处理有关。

每次,我不得不处理散列,它变得一团糟。我发现该语法对于哈希非常隐秘

很好地解释了哈希和哈希引用,它们的差异,何时需要它们等等。

最佳答案

一个简单的哈希接近数组。它们的初始化甚至看起来相似。首先是数组:

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

现在,让我们用散列(即关联数组)表示相同的信息:

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

Although they have the same name, the array @last_name and the hash %last_name are completely independent.

使用数组,如果我们想知道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",
    },
);

Internally, the keys and values of %personal_info are all scalars, but the values are a special kind of scalar: hash references, created with {}. The references allow us to simulate "multi-dimensional" hashes. For example, we can get to Wilma via

$personal_info{Flintstone}->{SPOUSE}

请注意,Perl允许我们省略下标之间的箭头,因此上述等效于

$personal_info{Flintstone}{SPOUSE}

如果您想了解更多有关Fred的信息,那么可以进行很多输入,因此您可能会像游标一样获取引用:

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

Because $fred in the snippet above is a hashref, the arrow is necessary. If you leave it out but wisely enabled use strict to help you catch these sorts of errors, the compiler will complain:

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;

Without the backslash, add_barney would have gotten a copy that's thrown away as soon as the sub returns.

Note also the use of the "fat comma" (=>) above. It autoquotes the string on its left and makes hash initializations less syntactically noisy.

回复