哈希引用

散列引用是标量,它包含指向包含散列数据的内存位置的指针。因为标量直接指向散列本身,所以当它传递给子例程时,对散列所做的更改不像常规散列那样是子例程的本地,而是全局的。

首先,让我们检查一下将普通哈希传递给子例程并在其中修改时会发生什么:

use strict;
use warnings;
use Data::Dumper;

sub modify
{
    my %hash = @_;

    $hash{new_value} = 2;

    print Dumper("Within the subroutine");
    print Dumper(\%hash);

    return;
}

my %example_hash = (
    old_value   => 1,
);

modify(%example_hash);

print Dumper("After exiting the subroutine");
print Dumper(\%example_hash);

结果如下:

$VAR1 = 'Within the subroutine';
$VAR1 = {
          'new_value' => 2,
          'old_value' => 1
        };
$VAR1 = 'After exiting the subroutine';
$VAR1 = {
          'old_value' => 1
        };

请注意,在我们退出子例程之后,哈希保持不变; 对它的所有更改都是修改子例程的本地更改,因为我们传递了哈希的副本,而不是哈希本身。

相比之下,当你传递 hashref 时,你将地址传递给原始哈希,因此子例程中所做的任何更改都将对原始哈希进行更改:

use strict;
use warnings;
use Data::Dumper;

sub modify
{
    my $hashref = shift;

    # De-reference the hash to add a new value
    $hashref->{new_value} = 2;

    print Dumper("Within the subroutine");
    print Dumper($hashref);

    return;
}

# Create a hashref
my $example_ref = {
    old_value   => 1,
};

# Pass a hashref to a subroutine
modify($example_ref);

print Dumper("After exiting the subroutine");
print Dumper($example_ref);

这将导致:

$VAR1 = 'Within the subroutine';
$VAR1 = {
          'new_value' => 2,
          'old_value' => 1
        };
$VAR1 = 'After exiting the subroutine';
$VAR1 = {
          'new_value' => 2,
          'old_value' => 1
        };