什么是Perl中匿名的哈希?(What are anonymous hashes in perl?)

2019-08-05 17:10发布

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

究竟什么是Perl的“匿名哈希”吗?

Answer 1:

这是可被存储在一个标量变量的散列的引用。 正是像一个普通的哈希值,除了大括号{...}创建一个散列的引用

注意在这些例子不同括号的用法:

%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"


Answer 2:

当你需要参考散列和一个名为哈希不便或不必要您使用匿名哈希。 举例来说,如果你想一个散列传递给函数,你可以写

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有知道的不一般的方式,数据只能通过其引用访问。



Answer 3:

这是很简单的。 它们允许你写

push @hashes, { ... };

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

代替

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

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

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



Answer 4:

什么“匿名”是一种数据结构,在某种程度上它没有得到名称中使用。

你的问题混淆了大家这个页面上的其他人,因为你的例子显示,你给一个名称为您创建的哈希值,因此它不再是匿名的。

例如 - 如果你有一个子程序,你想返回一个哈希,你可以写这样的代码: -

return {'hello'=>123};

因为它没有名字出现 - 它是匿名的。 阅读关于通过引入参考,这是不一样的东西来放松额外的混乱其他人都在此页上添加。

这又是一个匿名的哈希值(空单):

{}

这是一个匿名的哈希值与它的东西:

{'foo'=>123}

这是一个匿名(空)阵列:

[]

这是一个匿名的阵列,以在它的东西:

['foo',123]

很多时候人们使用这些东西的时候,他们确实试图神奇地把他们其他数据结构里面,没有给他们一个废物的时刻暂时的名字时这样做的麻烦。

例如 - 你可能希望有一个散列数组的中间!

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

该数组有3种元素 - 最后一个元素是一个哈希! ($阵列[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


文章来源: What are anonymous hashes in perl?