Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl $与命名输入或循环参数有何不同?_Perl_Perlvar - Fatal编程技术网

Perl $与命名输入或循环参数有何不同?

Perl $与命名输入或循环参数有何不同?,perl,perlvar,Perl,Perlvar,由于我经常使用$,我想更好地了解它的用法就我所理解和使用的而言,它是隐式值的全局变量 由于$u似乎是被设置的,除了可读性之外,还有什么理由在$ustrong>上使用命名循环变量吗 在什么情况下,美元是一个全局变量有什么关系 所以如果我使用 for (@array){ print $_; } 甚至 print $_ for @array; 它的效果与 for my $var (@array){ print $var; } 但它的工作原理是一样的吗?我想不完全是这样,但实际的区

由于我经常使用$,我想更好地了解它的用法就我所理解和使用的而言,它是隐式值的全局变量

由于$u似乎是被设置的,除了可读性之外,还有什么理由在$ustrong>上使用命名循环变量吗

在什么情况下,美元是一个全局变量有什么关系

所以如果我使用

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?