2

为什么第二次调用 printHash 时哈希为空?

my %hash = ();
addToHash(\%hash);
printHash(\%hash);

sub addToHash {
  my %hash = %{$_[0]};
  $hash{"test"} = "test";
  printHash(\%hash);
} 

sub printHash {
  print "printHash: \n";
  my %hash = %{$_[0]};
  foreach my $key (keys %hash) {
      print "key: $key, value: $hash{$key}\n";      
  }
}

输出:

打印哈希:

键:测试,值:测试

打印哈希:

4

4 回答 4

7

sub addToHash {
  my %hash = %{$_[0]};
  $hash{"test"} = "test";
  printHash(\%hash);
}

my %hash创建一个新的散列,将参数引用的散列复制到其中。你要

sub addToHash {
  my $hr = $_[0];
  $hr->{"test"} = "test";
  printHash($hr);
}

为了修改原始哈希。

于 2012-09-05T20:12:31.637 回答
5

因为该addToHash函数正在将键值对添加到第一个变量的副本中。%hash

my %hash = %{$_[0]}

取消引用中的哈希引用,$_[0]但分配my %hash创建哈希内容的新副本。如果要addToHash影响输入哈希引用,仍然需要将其作为哈希引用:

sub addToHash {
    my $hashref = $_[0];
    $hashref->{"test"} = "test";
    printHash( $hashref );
}

试试这个练习来了解使用散列和引用散列之间的区别。

%a = (foo => "bar");       # hash
$b = { foo => "bar" };     # reference to hash

%c = %a;                   # new copy of a hash
$c{"foo"} = "baz";         # changes the copy of %a, but not %a
print $a{"foo"};           # still outputs "bar"

$d = $b;                   # $d is reference to same hash that $b points to
$d->{"foo"} = "baz";       # changes $b
print $b->{"foo"};         # now outputs "baz"

$e = \%a;                  # $e is a reference to hash %a
$e->{"foo"} = "baz";       # changes %a
print $a{"foo"};           # now outputs "baz"
于 2012-09-05T20:11:13.630 回答
1

您的 subrutine 中有 local %hash,因此您不会更改 main-scope 中的那个。

于 2012-09-05T20:12:16.487 回答
0

您可能希望直接使用哈希别名(在您的情况下为$_[0])。

于 2012-09-05T21:36:17.473 回答