最近尝试获取一个“获取匹配括号的索引”的算法。虽然 perl 语言有些问题,但我能理解该算法的含义。
perl 语法并不晦涩,并且可以通过man perl...
文档获得很多信息。
my
但我对循环行为有点困惑for
。man perlsyn
说:
如果变量前面带有关键字“my”,则该变量具有词法作用域,因此仅在循环内可见。否则,该变量隐式地位于循环中,并在退出循环时恢复其以前的值。如果变量之前用“my”声明,则它使用该变量而不是全局变量,但它仍然位于循环中。这种隐式本地化仅发生在非 C 样式循环中。
我知道“非 C 风格循环”是指那些不像的循环for (...;...;...){...}
。
第一句话可以通过以下方式显示,类似于文档中显示的示例:
$i = 'samba';
# If the variable is preceded with the keyword "my", then it is lexically scoped, and is therefore visible only within the loop.
for (my $i = 1; $i <= 4; $i++) {
print "$i\n";
}
print "$i\n";
# 1
# 2
# 3
# 4
# samba
但我不明白第二点是什么意思:
$inner = 'samba';
for ($i = 1; $i <= 4; $i++) {
$inner = $i + 1;
}
print "inner: $inner\n";
# inner: 5
这里所谓的“本地”var$inner
似乎修改了外部的var,并且“以前的值”'samba'
无法“恢复”。
第三,我们可以对上面的例子做一些小的调整:
$inner = 'samba';
for ($i = 1; $i <= 4; $i++) {
my $inner = $i + 1;
}
print "inner: $inner\n";
# inner: samba
这对于“而不是全局的”来说是可以正常工作的。
如何理解循环my
中的行为for
,尤其是上面引用中的第二句?
后续澄清 choroba 的回答提示:当使用正确的“非 C 风格循环”时,第 1 句和第 2 句似乎意味着是否my
用于 var 具有相同的效果。但事实并非如此。
sub foo { print "foo: $x\n"; }
$x = 7;
for $x (1 .. 3) { # Implicit localisation happens here.
print "$x\n";
print "global $::x\n"; # Prints 1 .. 3 correspondingly.
foo(); # Prints 1 .. 3 correspondingly.
}
print $x; # Prints 7.
$x = 7;
for my $x (1 .. 3) { # Implicit localisation happens here.
print "$x\n";
print "global $::x\n"; # Always prints 7.
foo(); # Always prints 7.
}
print $x; # Prints 7.
这只是和之间的区别local
my
,仅意味着动态范围与词法范围,正如那里的最佳答案所示,这也在文档中有所说明。
局部变量只是为全局变量(即包变量)赋予临时值。它不会创建局部变量。这称为动态作用域。词汇作用域由我的...完成。
第三个句子示例可以更新:
$i = 'former';
my $i = 'samba';
for $i (1 .. 4) {
print "$i\n";
}
# > still localized to the loop
# i.e. uses the outside variable value but maybe there are more than one choices. The doc says to choose "my $i = 'samba';".
print "$i\n"; # not use 'former'
# 1
# 2
# 3
# 4
# samba
针对 ikegami 的回答的后续问题:
如果我们添加:
my $x = 7;
for $x (1 .. 3) { # Implicit localisation happens here.
print "$x\n";
print "global $::x\n"; # Prints nothing for $::x.
foo(); # Prints nothing for $x.
}
print $x; # Prints 7.
对于上面的sub foo { print "foo: $x\n"; } ...
例子,后者$::x
也不能访问后者定义的全局变量$x = 7;
。恕我直言,my
创建一个新的变量不应该影响那个全局变量。
但是如果我们将后者的 var 定义为our $x = 7;
文档中所说的“包(即全局)变量的词汇别名”。那么一切都会像以前一样工作。这是什么原因呢?
非 C风格是
它的工作原理如下:
文档没有讨论其他非循环变量。变量范围的一般规则适用于它们。
另外,养成使用strict的习惯。它使变量范围更加明确和可控。
要本地化全局变量,请使用local。
首先我要说的是,除了使用时,你总是想要。
my
$_
演示:
输出:
演示:
输出:
换句话说,该代码在功能上等同于以下内容:
输出: