理解Perl中的引用

4

我正在尝试理解有关Perl中引用的教程。

perldoc perlreftut

到目前为止,使用下面的代码,我正在初始化一个空哈希表:
my %table

以下是整个程序

#!/usr/bin/perl -w 
use strict;

my %table;

while (<DATA>) {
chomp;
my ($city, $country) = split /, /;
#$table{$country} = [] unless exists $table{$country};
push @{$table{$country}}, $city;

print @{$table{$country}};
}



__DATA__
Chicago, USA
Frankfurt, Germany
Berlin, Germany
Washington, USA
Helsinki, Finland
New York, USA

有人能解释一下下面这行代码吗?因为我看到一个引用(我认为是)在这里,但它被初始化为一个哈希表 %table。
push @{$table{$country}}, $city;

因此,在第一个迭代中,它看起来像这样: %table =('USA'=> [ 'Chicago']); $city 是 '芝加哥' 会被推入引用 $table{$country} 中,其中 @{ $table {$country}} 是数组引用; 如果我错了,请纠正我,是 autovivification 技术将 %table 中的内容填充进去的吗? - BioRod
@BioRod,在第一次迭代后,它确实看起来像%table = ( 'USA' => [ 'Chicago' ] );。我已经将其添加到我的答案中。/// $table{$country}是数组引用。@{ $table{$country} }是数组。/// 自动创建是创建引用和数组并将引用放入$table{$country}的过程。 - ikegami
2个回答

8
你正在声明哈希表%table。当你告诉Perl有一个词法作用域变量时,这就是声明。当你第一次给一个变量赋值时,这就是初始化。你没有初始化它,所以Perl会放置一个默认值。因为它是一个哈希表,它开始为空列表(),相当于false
在这一行中,你确实有一个解引用运算符。
push @{$table{$country}}, $city;

它说将值$table{$country}作为数组引用,解引用它,然后将$city推入该数组。有一个名为auto-vivification的功能会在值被推入之前自动创建必要的数组引用。
因此,在第一轮输入结束后,您现在拥有这个数据结构:
%table = ( 'USA' => [ 'Chicago' ] )

%table是一个哈希表,但其中的键USA保存了一个数组引用。

要在Perl中创建多级数据结构,您需要使用引用。但第一层不需要是引用,它可以是哈希表或数组。


4
在Perl中,使用my声明一个词法变量的同时也对其进行初始化。标量被初始化为undef,而哈希和数组则被初始化为空。 - ikegami
2
自动引用链接非常有帮助。 - BioRod

8

%table是一个哈希表,
$table{$country}是一个指向数组的引用,
@{ $table{$country} }是被引用的数组。

这种数据结构称为“哈希表的数组引用”,简称“哈希数组”,缩写为“HoA”。


但是,这个引用和数组从哪里来呢?它们是自动创建的,也就是说,当你将$table{$country}视为指向数组的引用时,Perl会为你创建它们。

换句话说,

push @{ $table{$country} }, $city

是...的缩写

push @{ $table{$country} //= [] }, $city

所以,在第一次“push”之后,您将从一个空哈希转换为具有以下内容的哈希:
%table = ( 'USA' => [ 'Chicago' ] );

文档:


push @{ $table{$country} //= [] }, $city timtowtdi or better tamswtdi There are many shorter ways to do it. - gaussblurinc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接