2

printHash の 2 回目の呼び出しでハッシュが空になるのはなぜですか?

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

サブルーチンにローカル%hashがあるため、メインスコープのものを変更していません。

于 2012-09-05T20:12:16.487 に答える
0

ハッシュエイリアス(この場合は$_[0]) を直接使用することもできます。

于 2012-09-05T21:36:17.473 に答える