相信很多人都写过下面这种函数,把参数当作hash引用来赋值:
sub foo {
my $hash = shift;
$hash->{foo} = 'bar';
}
然后这样调用:
foo($a);
调用之后,$a就变成了一个hash引用,里面包含了 foo => 'bar' 这一对值。 当然你可能会说,干嘛要在foo里面修改参数,直接return $hash不行吗。 当然可以,而且我也推荐使用return的方式, 不过有时候foo函数可能会很复杂,或者由于其他的原因而不得不使用修改参数的方式。
且慢!这种用法有时候会会失败。看下面的例子:
#!/usr/bin/perl
use Data::Dumper;
sub foo {
my $h = shift;
$h->{hello} = 'World!';
}
my $a;
my $b = {};
foo($a); print Dumper($a);
foo($b); print Dumper($b);
运行结果:
$VAR1 = undef;
$VAR1 = {
'hello' => 'World!'
};
为什么$a执行foo后仍然为undef,而$b就有值?
这是因为,my $a; 没有对$a初始化,此时$a的值为undef。 而调用foo时,参数实际上是传值调用,$a的undef值被赋给了$h变量, 此时$h = undef。而下一行将$h作为hash引用赋值时,系统会自动为$h赋一个空引用作为初始值。 ——但是,这个空引用以及接下来赋给的 hello => 'World!' 的值不会传回给外面的 $a,因为是值传递!
而$b则不同,初始化成一个空hash引用,这样传递给foo的就是个真正的引用值, 这样 hello => 'World!'的赋值可以赋给该引用。
所以,在使用hash引用时,初始化是非常必要的。