perl中的匿名哈希是什么?

时间:2013-01-05 19:37:20

标签: perl data-structures perl-data-structures hash

$hash = { 'Man' => 'Bill',
          'Woman' => 'Mary,
          'Dog' => 'Ben'
        };

Perl的“匿名哈希”到底是做什么的?

4 个答案:

答案 0 :(得分:18)

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

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

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

如果您想要将哈希作为参数传递给子例程,那么这很有用:

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

sub foo {
    my ($hash, @args) = @_;
    ...
}

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

my %hash = ( foo => { bar => "baz" } );  # $hash{foo}{bar} is now "baz"

答案 1 :(得分:12)

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

my %hash = (a => 1, b => 2);
mysub(\%hash);

但是如果不需要通过名称%hash访问哈希,那么你可以等效地写

mysub( {a => 1, b => 2} );

无论您何时需要对哈希的引用,尤其是在构建嵌套数据结构时,都会派上用场。而不是

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,
);

你可以写

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

并添加成员

$crew{jess} = { age => 4, position => "ship's cat" };

更整洁
my %newperson = ( age => 4, position => "ship's cat" );
$crew{jess} = \%newperson;

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

my $crew_member = $crew{bill}

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

答案 2 :(得分:5)

这很简单。他们允许你写

push @hashes, { ... };

f(config => { ... });

而不是

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

my %config = ( ... );
f(config => \%config);

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

答案 3 :(得分:3)

任何事情"匿名"是一种数据结构,它以一种不会得名的方式使用。

您的问题混淆了此页面上的其他所有人,因为您的示例显示您为您创建的哈希命名,因此它不再是匿名的。

例如 - 如果您有一个子例程并且想要返回一个哈希,那么您可以编写以下代码: -

return {'hello'=>123};

因为它没有名字 - 它是匿名的。请继续阅读,通过引入引用来解除其他人在此页面上添加的额外混淆,这些引用并不相同。

这是另一个匿名哈希(空的哈希):

{}

这是一个带有内容的匿名哈希:

{'foo'=>123}

这是一个匿名(空)数组:

[]

这是一个包含其中某些内容的匿名数组:

['foo',123]

大多数情况下,当人们使用这些东西时,他们真的试图将它们神奇地放入其他数据结构中,而不必在执行此操作时给它们留下浪费时间的临时名称。

例如 - 您可能希望在数组中间使用哈希值!

@array=(1,2,{foo=>3});

该数组有3个元素 - 最后一个元素是哈希! ($ array [2] - > {foo}是3)

perl -e '@array=(1,2,{foo=>1});use Data::Dumper;print Data::Dumper->Dump([\@array],["\@array"]);'
$@array = [
            1,
            2,
            {
              'foo' => 1
            }
          ];

有时您想要传递整个数据结构,而只是想使用指针或引用数据结构。在perl中,您可以通过添加" \"在变量前面;

%hashcopy=%myhash;     # this duplicates the hash
$myhash{test}=2;       # does not affect %hashcopy
$hashpointer=\%myhash; # this gives us a different way to access the same hash
$hashpointer->{test}=2;# changes %myhash
$$hashpointer{test}=2; # identical to above (notice double $$)

如果你疯了,你甚至可以引用匿名哈希:

perl -e 'print [],\[],{},\{}'
ARRAY(0x10eed48)REF(0x110b7a8)HASH(0x10eee38)REF(0x110b808)

有时perl很聪明,知道你真的意味着引用,即使你没有特别说出来,就像我的第一次"返回"例如:

perl -e 'sub tst{ return {foo=>bar}; }; $var=&tst();use Data::Dumper;print Data::Dumper->Dump([\$var],["\$var"]);'     
$var = \{
       'foo' => 'bar'
     };

或: -

perl -e 'sub tst{ return {foo=>bar}; }; $var=&tst(); print "$$var{foo}\n$var->{foo}\n"'
bar
bar