2012-09-05 40 views
2

为什么printHash的第二次调用时散列值为空?perl:在子例程中添加散列项丢失

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";  
    } 
} 

输出:

printHash:

键:测试,值:测试

printHash:

回答

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

你在你的subrutine具有本地%hash和这样你就不会改变一个在主范围。

7

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

my %hash创建新的哈希到您复制由参数引用的哈希值。你想要

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

为了修改原始散列。

+0

'$ _ [0] - > {“test”} =“test”;'?几乎没有什么值得为它创造一个新的变量。 – TLP

+1

实际使用,没有。为了与原文进行比较,我认为这是说明性的。 – chepner

0

你可能想直接使用散列别名(在你的情况下,$_[0])。