[Perl]用hash引用时别忘了初始化
相信很多人都写过下面这种函数,把参数当作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引用时,初始化是非常必要的。