Perl中@_的含义是什么?

109

@_ 在 Perl 中的含义是什么?

9个回答

128

perldoc perlvar是查询任何特定Perl变量信息的第一站。

引用:

@_:在子例程中,数组@_包含传递给该子例程的参数。

更多详细信息可以在从perlvar链接的perldoc perlsub(Perl子例程)中找到:

传入的任何参数都会显示在数组@_中。

因此,如果您使用两个参数调用函数,则这些参数将存储在$_[0]$_[1]中。

数组@_是一个本地数组,但它的元素是实际标量参数的别名。特别地,如果更新了元素$_[0],则相应的参数也将被更新(或者如果无法更新,则会出错)。

如果参数是在函数调用时不存在的数组或哈希元素,则仅在修改它或对其引用时才创建该元素。(早期的某些Perl版本创建元素,无论是否分配给该元素。)将整个数组@_分配给它会删除该别名,并且不会更新任何参数。


谢谢,我最近才习惯于查看perldoc,并且我发现这些网页非常有用:http://perldoc.perl.org/perlvar.html 做一个启动这个Web页面的Perl存根也不错...网页的格式对我帮助很大。 - aschultz

29

通常情况下,您可以使用@_变量扩展传递给子程序的参数:

sub test{
  my ($a, $b, $c) = @_;
  ...
}

# call the test sub with the parameters
test('alice', 'bob', 'charlie');

这是据perlcritic宣称正确的方法。


2
这是我第一次不同意 perlcritic,个人认为对于一个函数来说这样做是最好的,但对于一个方法来说,将 self 引用进行 shift 操作,然后解包 @_ 数组是有用的。这使得它清楚地表明这是一个方法,并且该方法需要特定的参数。 - Joel Berger
1
我可能应该在之前就使用/了解PERLCritic,但我没有。感谢您在这个例子中使用它。有时候你随口提到的东西可以帮助别人学习全新的东西。 - aschultz
这很简单,易于理解。 - R.G.Krish

13

5
实际上,你在谷歌搜索中的第一个结果现在链接到这个页面。 - Gabriel Southern
七年后,在互联网时间中是一个永恒的时期。这就是为什么我既链接到了第一个结果,又引用了相关部分:仅依赖于谷歌是非常幼稚的。 - Piskvor left the building
1
虽然已经过去了很多年,但仍然很烦人的是看到一些回答暗示你应该通过谷歌搜索来找到问题的答案。对于那些通过谷歌搜索得到答案的人来说,这是无意义的信息。 - Gabriel Southern
2
是的,搜索是正确的第一步,但在你的回答中包含搜索指令并不是必要的。这是多余的信息,没有任何价值,而且具有讽刺意味,因为如果有人按照你的回答中的搜索链接进行搜索,他们会回到起点。 - Gabriel Southern
1
所有这些“谷歌一下”回答现在看来都已经过时了。 - Austin Adams
显示剩余4条评论

11
问题是Perl中@_的意思。 回答这个问题的是,就像$_在Perl中代表一样,@_同样代表 他们

似乎没有人提到其关键含义-以及他们。

它们通常被用作代词,或者有时用作主题化语言标记。

它们通常有名词先行语,但不总是。


7

在大多数情况下,您也可以使用 shift 键来处理单个变量:

$var1 = shift;

这是一个话题,您应该进一步研究,因为Perl有许多有趣的方法可以在您的子例程中访问外部信息。


3
太酷了,有人因我发表另一种类似方法而给我点了踩。我知道我没有直接回答问题,因为已经有人回答了,但我提供了一种新的形式,新的Perl程序员经常会感到困惑。 - hockfan86

5

所有 Perl 的 "特殊变量" 列在 perlvar 文档页面中。


(注:该页面列出了 Perl 中的特殊变量列表)

2
此外,如果一个函数返回一个数组,但是该函数被调用时没有把返回的数据分配给任何变量,如下所示。这里调用了split()函数,但它没有被赋给任何变量。我们可以通过@ _稍后访问其返回的数据:
$str = "Mr.Bond|Chewbaaka|Spider-Man";
split(/\|/, $str);

print @_[0]; # 'Mr.Bond'

这将会分割字符串$str并设置数组@_

1

永远不要尝试编辑@_变量!!!它们必须不被操作。否则,您会得到一些意想不到的效果。例如...

my $size=1234;
sub sub1{
  $_[0]=500;
}
sub1 $size;

在调用sub1之前,$size的值为1234。但是调用后变成了500(!!)。所以不要编辑这个值!!!你可以传递两个或更多的值,并在子程序中更改它们,所有这些值都将被更改!我从未见过这种效果的描述。我看到的程序也会将@_数组保留为只读。只有这样,你才能安全地传递变量而不改变内部子程序。你必须始终这样做:

sub sub2{
  my @m=@_;
  ....
}

将 @_ 分配给本地子程序过程变量,然后与它们一起工作。

在一些深递归算法中,如果返回数组,则可以使用此方法来减少用于本地变量的内存占用。仅当返回的 @_ 数组相同时才能使用此方法。


1

@用于数组。

在Perl中的子程序或者函数调用时,您可以传递参数列表。在这种情况下,@_可用于将参数列表传递给函数:

sub Average{

    # Get total number of arguments passed.
    $n = scalar(@_);
    $sum = 0;

    foreach $item (@_){

        # foreach is like for loop... It will access every
        # array element by an iterator
        $sum += $item;
    }

    $average = $sum / $n;

    print "Average for the given numbers: $average\n";
}

函数调用

Average(10, 20, 30);

如果您观察上面的代码,请查看foreach $item(@_)这一行... 这里它传递了输入参数。

你应该始终使用 use strict。我已经编辑了你的子函数。 - EverythingRightPlace

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接