perl中的匿名哈希是什么?

use*_*308 17 perl hash data-structures perl-data-structures

$hash = { 'Man' => 'Bill',
          'Woman' => 'Mary,
          'Dog' => 'Ben'
        };
Run Code Online (Sandbox Code Playgroud)

Perl的"匿名哈希"究竟做了什么?

TLP*_*TLP 19

它是对可以存储在标量变量中的哈希的引用.它与常规哈希完全相同,只是大括号{...}创建对哈希的引用.

请注意这些示例中不同括号的用法:

%hash = ( foo => "bar" );   # regular hash
$hash = { foo => "bar" };   # reference to anonymous (unnamed) hash
$href = \%hash;             # reference to named hash %hash
Run Code Online (Sandbox Code Playgroud)

如果你想将哈希作为参数传递给子例程,这对于能够做到很有用:

foo(\%hash, $arg1, $arg2);

sub foo {
    my ($hash, @args) = @_;
    ...
}
Run Code Online (Sandbox Code Playgroud)

它是一种创建多级哈希的方法:

my %hash = ( foo => { bar => "baz" } );  # $hash{foo}{bar} is now "baz"
Run Code Online (Sandbox Code Playgroud)


Bor*_*din 12

当您需要引用哈希时,您使用匿名哈希,并且命名哈希是不方便或不必要的.例如,如果您想将哈希传递给子例程,则可以编写

my %hash = (a => 1, b => 2);
mysub(\%hash);
Run Code Online (Sandbox Code Playgroud)

但如果不需要通过其名称访问哈希%hash,则可以等效地写入

mysub( {a => 1, b => 2} );
Run Code Online (Sandbox Code Playgroud)

无论何时需要对哈希的引用,特别是在构建嵌套数据结构时,这都会派上用场.代替

my %person1 = ( age => 34, position => 'captain' );
my %person2 = ( age => 28, position => 'boatswain' );
my %person3 = ( age => 18, position => 'cabin boy' );

my %crew = (
  bill => \%person1,
  ben  => \%person2,
  weed => \%person3,
);
Run Code Online (Sandbox Code Playgroud)

你可以写

my %crew = (
  bill => { age => 34, position => 'captain' },
  ben  => { age => 28, position => 'boatswain' },
  weed => { age => 18, position => 'cabin boy' },
);
Run Code Online (Sandbox Code Playgroud)

并添加一个成员,

$crew{jess} = { age => 4, position => "ship's cat" };
Run Code Online (Sandbox Code Playgroud)

比它更整洁

my %newperson = ( age => 4, position => "ship's cat" );
$crew{jess} = \%newperson;
Run Code Online (Sandbox Code Playgroud)

当然,即使使用名称创建哈希,如果其引用在其他地方传递,则可能无法使用该原始名称,因此必须将其视为匿名.例如在

my $crew_member = $crew{bill}
Run Code Online (Sandbox Code Playgroud)

$crew_member现在实际上是对匿名哈希的引用,无论数据最初是如何构造的.即使数据(在某些范围内)仍然可访问,因为%person1没有一般的方法可以知道,并且数据只能通过其引用来访问.


ike*_*ami 5

这很简单.他们允许你写

push @hashes, { ... };

f(config => { ... });
Run Code Online (Sandbox Code Playgroud)

代替

my %hash = ( ... );
push @hashes, \%hash;

my %config = ( ... );
f(config => \%config);
Run Code Online (Sandbox Code Playgroud)

(如果你想知道引用的目的,那完全是另一个故事.)