在哈希中存储哈希

cru*_*ahl 5 perl hash

我在使用Perl脚本时遇到了麻烦.我尝试在哈希中存储哈希.脚本很简单:

use Data::Dumper;

my %h1=();
$h1{name}="parent";
my %h2=();
$h2{name}="child";

$h1{nested}=%h2; # store hash h2 in hash h1

print "h2:\n";
print Dumper(%h2); # works
print "h1{nested}:\n";
print Dumper($h1{nested}); # fails
Run Code Online (Sandbox Code Playgroud)

结果:

h2:
$VAR1 = 'name';
$VAR2 = 'child';
h1{nested}:
$VAR1 = '1/8';
Run Code Online (Sandbox Code Playgroud)

为什么$ h1 {nested}没有作为哈希转储,而是作为某种奇怪的标量(1/8)?

PS:即使这个问题听起来微不足道 - 我搜索了SO,但没有发现它之前被问过.PPS:我的Perl是为x86_64-linux-gnu-thread-multi构建的v5.10.1(*)(有53个已注册的补丁,有关详细信息,请参阅perl -V)

Fli*_*mzy 13

您只能在哈希中存储hashref:

$h1{nested}=\%h2;
Run Code Online (Sandbox Code Playgroud)

然后你会%h2通过这样做访问的名字

$h1{nested}->{name}
Run Code Online (Sandbox Code Playgroud)

在你的代码中,%h2被强制为标量上下文,它向你显示"1/8"值,并存储它.

  • 或者`$ h1 {nested} {name}`; 请参阅http://perlmonks.org/?node=References+quick+reference (2认同)

leo*_*loy 5

在perl中,存储在列表(散列或数组)中的值始终是标量.鉴于此,将哈希存储在另一个哈希中的唯一方法是存储对它的引用.

$h1{'nested'} = \%h2;
Run Code Online (Sandbox Code Playgroud)

或者也

$h1{'nested'} = { 'name'=>'child' };
Run Code Online (Sandbox Code Playgroud)

(右侧的大括号是对匿名散列的引用).

顺便说一句,不引用键中的文字通常被认为是不好的做法,请看这里


Dav*_* W. 5

为什么 $h1{nested} 没有转储为哈希,而是转储为某种奇怪的标量 (1/8)?

因为您将其存储在标量上下文中!

当你这样做时:

$h1{nested} = %h2;
Run Code Online (Sandbox Code Playgroud)

您正在存储一个标量。由于%h2是一个散列,因此您将获得 ol'分数字符串。根据Perldoc 网站

如果您在标量上下文中计算哈希,则如果哈希为空,则返回 false。如果存在任何键/值对,则返回true;更准确地说,返回的值是一个字符串,由已使用的桶数和已分配的桶数组成,并用斜杠分隔。

这解释了1/8你得到的。

您需要做的是将哈希值存储为另一个哈希值中的引用。正如其他人指出的那样,应该是:

$h1{nested} = \%h2;
Run Code Online (Sandbox Code Playgroud)

哈希名称之前的反斜杠给出了存储哈希的内存位置。您可以使用花括号,但我更喜欢使用反斜杠表示法。

在您的计算机上查看perldoc prelreftut(或在我链接到的网页上)。这将告诉您如何创建诸如列表的列表、散列或散列、散列列表以及列表的散列之类的东西。只是警告一下:如果你变得太复杂,它将很难维护,所以一旦你玩得很开心,请看一下perldoc 的 Perl 面向对象编程教程

perldoc命令包含大量 Perl 文档,包括所有 Perl 函数、系统上安装的 Perl 模块,甚至有关 Perl 语言的基本信息。