@_在Perl中是什么意思?


Answers:


118

perldoc perlvar是检查任何特殊名称的Perl变量信息的第一位。

报价单:

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

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

传入的所有参数都显示在数组中@_

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

该数组@_是一个局部数组,但其元素是实际标量参数的别名。特别是,如果元素$ _ [0]被更新,则相应的参数将被更新(或者,如果它不可更新,则会发生错误)。

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


谢谢,我只是最近才习惯于检查perldoc,并且发现这些网页很有用:perldoc.perl.org/perlvar.html 制作一个可以在网络上启动它的perl存根还不错...网页的格式对我有很大帮助。
aschultz '16

27

通常,使用变量扩展传递给子级@_参数:

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

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

perlcritic声称这是正确的方法


2
这是我不同意的一次,我perlcritic个人认为这对函数是最好的,但是对于方法来说,它对于shift自引用很有用,然后解压缩@_数组。这清楚表明这是一种方法,并且该方法采用某些参数
Joel Berger

我以前可能应该已经使用过PERLCritic,但是我没有。感谢您在本示例中使用它。有时,您临时引用的内容可以帮助某人学习对他们来说是全新的东西。
aschultz '16

10

一的第一主打搜索perl @_这个

@_是子程序的传入参数列表。

它还对此有更长更详细的解释。


3
实际上,您的Google搜索的第一个匹配项现在已链接到此页面。
加百列南部地区

... 7个多年的后,在互联网时代的永恒。这就是为什么我都链接到第一个结果并退出相关部分的原因:仅依靠Google会非常幼稚。
Piskvor在

1
确实是很多年后的事,但阅读答案仍然很烦人,这意味着您应该使用Google为该问题提供答案。对于由于谷歌搜索结果而阅读答案的人来说,这是毫无意义的信息。
加百列南部

我不同意。“搜索你的问题之前问一个问题”仍然是步0 stackoverflow.com/help/how-to-ask讨厌,也许-但这样是重复的问题了一堆可能已经回答了第一个查询机。
Piskvor于

2
是的,搜索是正确的第一步,但没有必要在搜索结果中包含搜索说明。这是多余的信息,没有任何价值,而且具有讽刺意味的是,如果有人遵循您答案中的搜索链接,则会将他们带回到起点。
加百列南部

10

问题是在Perl中@_ 意味着什么。该问题的答案是,只要$_手段在Perl,@_同样意味着他们

似乎没有人提及其意义的这一关键方面以及他们的意义

因此,它们既被用作代词,有时也被用作主题化器。

它们通常具有名义上的先例,尽管并非总是如此。


7

在大多数情况下,您还可以对单个变量使用shift:

$var1 = shift;

由于Perl有许多有趣的方式可以访问子例程中的外部信息,因此,您应该对此主题进行进一步研究。


3
太酷了,谁给我投反对票的原因仅仅是因为他发布了另一种做类似事情的方法。我意识到我没有直接回答这个问题,因为有人已经回答了这个问题,但是我提供了另一种形式,新的Perl程序员经常被它弄糊涂。
hockfan86


2

同样,如果一个函数返回一个数组,但是调用该函数时未将其返回的数据分配给任何变量,如下所示。此处调用split(),但未将其分配给任何变量。我们稍后可以通过@_访问其返回的数据:

$str = "Mr.Bond|Chewbaaka|Spider-Man";
split(/\|/, $str);

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

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


1

@ 用于数组。

在子例程中或在Perl中调用函数时,可以传递参数列表。在这种情况下,@_可以使用is将参数列表传递给函数:

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

0

永远不要尝试编辑@_变量!!!!切勿触摸它们。否则,您会得到意想不到的效果。例如...

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

在调用sub1 $ size之前包含1234。但是在500(!!)之后,因此您不要编辑此值!!!您可以传递两个或多个值,然后在子例程中对其进行更改,所有这些值都将被更改!我从未见过这种效果的描述。我见过的程序也将@_ array保留为只读。并且只有您可以安全地传递变量,才不要更改内部子例程,您必须始终这样做:

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

将@_分配给本地子例程过程变量,然后使用它们。同样,在一些深化数组的深度递归算法中,您可以使用这种方法来减少用于本地变量的内存。仅当返回@_数组相同时。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.