先来看一段 Perl 脚本:
my $name = “first”;
print $name . “\t at ” . \$name . “\n”;
for(my $i = 0; $i < 2; $i++) {
my $name = "loop_" . $i;
if (1 < 3) {
print $name . "\t at " . \$name . "\n";
my $name = "if_A";
print $name . "\t at " . \$name . "\n";
{
my $name = "blank";
print $name . "\t at " . \$name . "\n";
}
print $name . "\t at " . \$name . "\n";
}
if (1 < 4) {
print $name . "\t at " . \$name . "\n";
my $name = "if_B";
print $name . "\t at " . \$name . "\n";
}
print $name . "\t at " . \$name . "\n";
}
print $name . "\t at " . \$name . "\n";
}
sub showVars_2 {
my $name = "first";
print $name . "\t at " . \$name . "\n";
for(my $i = 0; $i < 2; $i++) {
$name = "loop_" . $i;
if (1 < 3) {
print $name . "\t at " . \$name . "\n";
$name = "if_A";
print $name . "\t at " . \$name . "\n";
{
$name = "blank";
print $name . "\t at " . \$name . "\n";
}
print $name . "\t at " . \$name . "\n";
}
if (1 < 4) {
print $name . "\t at " . \$name . "\n";
$name = "if_B";
print $name . "\t at " . \$name . "\n";
}
print $name . "\t at " . \$name . "\n";
}
print $name . "\t at " . \$name . "\n";
}
showVars();
print "--------------\n";
showVars_2();
这里面有 2 个函数,两者之间的区别,就是变量的定义方式不同。
第一个函数,多次使用 my 声明变量。Perl 会在每一个局部区域内,比如说大括号 {} 内,实现一个命名空间。
也就是说,在不同的代码段,相同的变量名,实际上指向了不同的内存地址。
第一个函数体内,首先声明了一个变量 $name,他的作用域是整个函数,但在 for 循环体内,又用 my 声明了 $name 变量,因为 for 是一个封闭的结构,在 {} 里面就可以产生一个新的命名空间,此时 $name 指向了一个新的内存地址。这一点可以在后面的输出结果中看到。
由此,引发一个值得思考的问题:
如果在循环体内部用 my 去声明变量,那么循环执行多少次,就会有多少个变量的副本,这会浪费很多内存空间。
这一点是跟其他类 C 语言是有很大区别的。
所以,如果你要想利用 Perl 的命名空间,那么只要多注意代码段的作用范围,编程的时候能感受到 Perl 十分强大的便利性。
需要注意的,就是避免在循环体中使用 my 声明,浪费内存空间不说,还会影响程序的性能。
说了半天,还是看一看实际的结果吧:
first at SCALAR(0x182fb10)
loop_0 at SCALAR(0x182fbb8)
if_A at SCALAR(0x182fc24)
blank at SCALAR(0x182fc84)
if_A at SCALAR(0x182fc24)
loop_0 at SCALAR(0x182fbb8)
if_B at SCALAR(0x182fd5c)
loop_0 at SCALAR(0x182fbb8)
loop_1 at SCALAR(0x182fd5c)
if_A at SCALAR(0x182fc84)
blank at SCALAR(0x276164)
if_A at SCALAR(0x182fc84)
loop_1 at SCALAR(0x182fd5c)
if_B at SCALAR(0x182fc24)
loop_1 at SCALAR(0x182fd5c)
first at SCALAR(0x182fb10)
————–
first at SCALAR(0x182fe88)
loop_0 at SCALAR(0x182fe88)
if_A at SCALAR(0x182fe88)
blank at SCALAR(0x182fe88)
blank at SCALAR(0x182fe88)
blank at SCALAR(0x182fe88)
if_B at SCALAR(0x182fe88)
if_B at SCALAR(0x182fe88)
loop_1 at SCALAR(0x182fe88)
if_A at SCALAR(0x182fe88)
blank at SCALAR(0x182fe88)
blank at SCALAR(0x182fe88)
blank at SCALAR(0x182fe88)
if_B at SCALAR(0x182fe88)
if_B at SCALAR(0x182fe88)
if_B at SCALAR(0x182fe88)