Perl $与命名输入或循环参数有何不同?
由于我经常使用$,我想更好地了解它的用法就我所理解和使用的而言,它是隐式值的全局变量 由于$u似乎是被设置的,除了可读性之外,还有什么理由在$ustrong>上使用命名循环变量吗 在什么情况下,美元是一个全局变量有什么关系 所以如果我使用Perl $与命名输入或循环参数有何不同?,perl,perlvar,Perl,Perlvar,由于我经常使用$,我想更好地了解它的用法就我所理解和使用的而言,它是隐式值的全局变量 由于$u似乎是被设置的,除了可读性之外,还有什么理由在$ustrong>上使用命名循环变量吗 在什么情况下,美元是一个全局变量有什么关系 所以如果我使用 for (@array){ print $_; } 甚至 print $_ for @array; 它的效果与 for my $var (@array){ print $var; } 但它的工作原理是一样的吗?我想不完全是这样,但实际的区
for (@array){
print $_;
}
甚至
print $_ for @array;
它的效果与
for my $var (@array){
print $var;
}
但它的工作原理是一样的吗?我想不完全是这样,但实际的区别是什么
更新:
在本例中,$的作用域似乎是正确的。它不再是全球性的了吗?我使用的是5.12.3
#!/usr/bin/perl
use strict;
use warnings;
my @array = qw/one two three four/;
my @other_array = qw/1 2 3 4/;
for (@array){
for (@other_array){
print $_;
}
print $_;
}
正确打印1234One1234WO1234Three12344
对于全球美元,我预计1234412344123441234412344。。还是我遗漏了一些明显的东西
那么美元什么时候是全球性的呢
更新:
好的,在仔细阅读了各种答案和帕尔森之后,我得出了一个结论:
除了可读性之外,最好避免使用$,因为必须知道并考虑$的隐式本地化,否则可能会遇到意外行为
感谢您对此问题的澄清。$\u与第二个示例中使用的变量命名方式相同。$\u只是当前循环中当前项的快捷方式默认变量名,在执行快速、简单循环时键入时保存。我倾向于使用命名变量而不是默认变量。这使它更清楚它是什么,如果我碰巧需要做一个嵌套循环,就不会有冲突
由于$\是一个全局变量,如果您试图使用它从上一个代码块获得的值,则可能会得到意外的值。新代码块可能是循环或其他操作的一部分,这些操作将自己的值插入$\中,覆盖您期望的值。使用$\的风险在于它是全局的(除非您使用
local$\将其本地化),因此如果您在循环中调用的某个函数也使用$\时,这两种使用可能会相互干扰
出于我不清楚的原因,这只是偶尔会让我感到痛苦,但如果我在包中使用它,我通常会将$本地化 使用$\uuu
(隐式或显式)作为循环变量的典型故障模式是
for $_ (@myarray) {
/(\d+)/ or die;
foo($1);
}
sub foo {
open(F, "foo_$_[0]") or die;
while (<F>) {
...
}
}
美元(@myarray)的{
/(\d+)或模具;
富(1元);;
}
sub-foo{
打开(F,“foo$\u0]”或死亡;
而(){
...
}
}
其中,因为for
/foreach
中的循环变量绑定到实际列表项,这意味着while()
用从文件中读取的行覆盖@myarray
。除了它是许多函数的默认参数之外,它没有什么特别之处。如果用my
明确地在词汇上限定$\ucode>的范围,perl将使用$\ucode>的本地版本,而不是全局版本。这并没有什么奇怪的,它就像其他命名变量一样
sub p { print "[$_]"; } # Prints the global $_
# Compare and contrast
for my $_ (b1..b5) { for my $_ (a1..a5) { p } } print "\n"; # ex1
for my $_ (b1..b5) { for (a1..a5) { p } } print "\n"; # ex2
for (b1..b5) { for my $_ (a1..a5) { p } } print "\n"; # ex3
for (b1..b5) { for (a1..a5) { p } } print "\n"; # ex4
在发现perl将在循环退出时保留循环变量的原始值之前,您应该对输出有点迷惑(请参见perlsyn)
注意上面的ex2。在这里,第二个循环使用在第一个循环中声明的词汇范围$\uz
。微妙的,但预期的。同样,该值在退出时保留,因此两个循环不会相互干扰
are there reasons to use named loop variables over $_ besides readability?
问题不在于它们是否被命名。问题在于它们是“包变量”还是“词汇变量”
请参阅Perl“处理范围”中使用的两个变量系统的非常好的描述:
包变量是全局变量,因此应避免所有常见原因(如远距离操作)
避免包变量是一个“正确操作”或“更难注入bug”的问题,而不是一个“可读性”的问题
到处都是
更好的问题是:
In what cases is $_ local()ized for me?
有几个地方Perl会为您将$本地化,主要是foreach、grep和map。所有其他地方都要求您自己将其本地化(),因此,当您不可避免地忘记这样做时,您将注入一个潜在的bug。:-) 它似乎与命名变量不同,因为perlvar提到了副作用,因为它是全局的。关于可读性,我同意嵌套循环。这是正确的,我应该更清楚,特别是因为你提到了全局方面。如果您稍后尝试使用它,它可能已经初始化或初始化为您不期望的内容,或者您可能已经覆盖了您期望的值。我为此道歉。当我使用$时,它只在一个非常小的循环或映射的上下文中,所以我忘记了这一点。甚至,print for@array
;)要解决您的更新:$\uu
仍然是一个全局变量,但隐式地定位在每个循环中。例如,请参见。$man perlsyn
,查找Foreach循环。@mob:隐式本地化在每个for/Foreach循环中。在中没有隐式本地化,而()
loopLexical$\uuz
需要Perl v5.10或更高版本。是的,问正确的问题有时是最困难的部分;)当您在这样的子例程中使用$时,您应该有一个本地($,$)代码>也在那里。
In what cases is $_ local()ized for me?