请解释Perl中$_
和@_
的确切区别。
何时使用,由示例代码给出。
答案 0 :(得分:23)
在子例程中,数组@_
给出传递给给定子例程的参数。例如:
use strict;
use warnings;
sub print_em
{
foreach my $arg (@_)
{
print "You passed in $arg.\n";
}
}
print_em("foo","bar","baz");
输出
You passed in foo.
You passed in bar.
You passed in baz.
标量$_
通常用作循环中的变量。例如:
use strict;
use warnings;
# Note that we are not declaring a variable
# that takes on the values 1 through 5.
foreach(1..5)
{
print "$_\n";
}
输出结果为:
1
2
3
4
5
同样,我们可以略微重写上面的子例程print_em
sub print_em
{
foreach(@_)
{
print "You passed in $_.\n";
}
}
甚至更紧凑
sub print_em{ print "You passed in $_.\n" foreach(@_);}
变量$_
也可以用作某些函数的“默认参数”。例如:
use strict;
use warnings;
$_="foobar";
if(/bar/) #We do not have to write $_=~/bar/
{
print "matched!\n";
}
当然,输出matched!
。
请查看perldoc perlvar
以获取有关这些和Perl的其他“神奇变量”的更多信息。
答案 1 :(得分:8)
Jack Maney的回复涵盖了您的确切问题,但我也想注意一些事情:您不应该被变量的名称部分所迷惑。这个信号也很重要。 $_
和@_
是完全不同的变量,$foo
和@foo
以及$bar
和%bar
也是如此。 Perl将它们彼此完全分开存储。
答案 2 :(得分:3)
一个常见的例子与I / O有关。这段代码......
while(<>)
{
chomp;
print if(m/^chr1/);
}
...在功能上等同于此代码。
while(my $line = <STDIN>)
{
chomp($line);
print($line) if($line =~ m/^chr1/);
}
只要你有一个循环,就会填充$_
变量,但是还有一个更明确的语法。这段代码......
foreach(@a)
{
print;
chomp;
push(@b, $_)
}
...在功能上等同于此代码。
foreach my $value(@a)
{
print($value);
chomp($value);
push(@b, $value);
}
要记住$_
和其他神奇变量的一件事是它们对于一个新颖的程序员来说可能非常神秘。随着时间的推移,我越来越少地使用这些语言(希望)使其他人更容易理解代码的意图。
答案 3 :(得分:1)
$_
和@_
都不具备特殊性。除了是全球性的,它们完全是正常的变量。它们并不神奇。当分配给他们或从他们那里读取时,没有什么特别的事情发生。
经常使用@_
的原因是Perl放置了函数的参数。如果您希望将args传递给您的sub,则需要访问@_
。
sub f {
my ($x, $y) = @_;
...
}
经常使用$_
的原因是默认情况下某些Perl运算符会为其分配,而其他运算符则使用其值作为其参数的默认值。如果你接受它可以导致更短的代码,但你从来没有 来使用它。
for my $x (@x) { say $x; }
vs
for (@x) { say; }