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

use*_*855 63 perl hash language-features hash-reference

我想正确理解Perl中的哈希值.我不得不间歇性地使用Perl很长一段时间,而且大多数时候我都需要这样做,它主要与文本处理有关.

每次,我都要处理哈希,它会搞砸.我觉得哈希的语法非常神秘

哈希和哈希引用的好解释,它们的差异,当它们被要求等时将非常感激.

Gre*_*con 87

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

@last_name = (
  "Ward",   "Cleaver",
  "Fred",   "Flintstone",
  "Archie", "Bunker"
);
Run Code Online (Sandbox Code Playgroud)

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

%last_name = (
  "Ward",   "Cleaver",
  "Fred",   "Flintstone",
  "Archie", "Bunker"
);
Run Code Online (Sandbox Code Playgroud)

虽然它们具有相同的名称,但数组@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";
Run Code Online (Sandbox Code Playgroud)

使用哈希,它在语法上更直接:

print "Archie $last_name{Archie}\n";
Run Code Online (Sandbox Code Playgroud)

假设我们想要只用稍微丰富的结构来表示信息:

  • 切肉刀(姓氏)
    • 沃德(名字)
    • 六月(配偶的名字)
  • 打火石
    • 弗雷德
    • 威尔玛
  • 掩体
    • 阿奇
    • 伊迪丝

在引用出现之前,平键值哈希是我们能做的最好的,但引用允许

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

在内部,键和值%personal_info都是标量,但值是一种特殊的标量:哈希引用,用{}.创建.参考允许我们模拟"多维"哈希.例如,我们可以通过Wilma到达

$personal_info{Flintstone}->{SPOUSE}
Run Code Online (Sandbox Code Playgroud)

请注意,Perl允许我们省略下标之间的箭头,因此上述内容相当于

$personal_info{Flintstone}{SPOUSE}
Run Code Online (Sandbox Code Playgroud)

如果您想要了解有关Fred的更多信息,那么打字很多,所以您可以将引用作为游标的类型获取:

$fred = $personal_info{Flintstone};
print "Fred's wife is $fred->{SPOUSE}\n";
Run Code Online (Sandbox Code Playgroud)

因为$fred在上面的代码片段中是hashref,所以箭头是必需的.如果您将其删除但明智地启用use strict以帮助您捕获这些类型的错误,编译器将抱怨:

Global symbol "%fred" requires explicit package name at ...
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

没有反斜杠,add_barney只要子返回就会得到一个被丢弃的副本.

另请注意上面使用的"胖逗号"(=>).它自动引用其左侧的字符串,并使哈希初始化在语法上更加嘈杂.

  • 很棒的帖子:)。一条评论——也许一条警告注释值得“@_”别名参数,因此可以从子目录中更改它们(散列键除外)? (2认同)

Ala*_*avi 16

以下演示了如何使用散列和散列引用:

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";
Run Code Online (Sandbox Code Playgroud)

另见perldoc perldsc.

  • 就个人而言,我发现用"%hash"这个术语来描述一个哈希是很困惑的.将你的'%hash`重新标记为'%favorite`可能是一个好主意,只是为了将点回家.那么print语句会像'print'那样我最喜欢的玩具是$ favorite {toy}";` (8认同)

小智 10

哈希是Perl中的基本数据类型.它使用密钥来访问其内容.

散列引用是对散列的引用的缩写.引用是标量,即简单值.它是一个标量值,基本上包含指向实际散列本身的指针.

链接:perl中的散列和散列引用之间的区别 - Ubuntu论坛

删除的语法也有所不同.像C一样,perl对Hashes的作用如下:

delete $hash{$key};
Run Code Online (Sandbox Code Playgroud)

和哈希参考

delete $hash_ref->{$key};
Run Code Online (Sandbox Code Playgroud)

Perl中的哈希HOWTO是一个很好的资源,了解与散列与哈希散列引用

这里还有另一个链接,其中包含有关perl和引用的更多信息.


Sin*_*nür 7

请参阅perldoc perlreftut,它也可以在您自己的计算机命令行上访问.

引用是一个标量值,它引用整个数组或整个哈希值(或几乎任何其他哈希值).名称是您已经熟悉的一种参考.想想美国总统:一堆杂乱,不方便的血和骨头.但是要谈论他,或者在计算机程序中代表他,你所需要的只是简单方便的标量字符串"Barack Obama".

Perl中的引用类似于数组和哈希的名称.它们是Perl的私人内部名称,因此您可以确定它们是明确无误的.与"巴拉克奥巴马"不同,参考仅指一件事,你总是知道它所指的是什么.如果您有对数组的引用,则可以从中恢复整个数组.如果您有对哈希的引用,则可以恢复整个哈希.但是参考仍然是一个简单,紧凑的标量值.