2009-01-17 60 views
8

我正在浏览一些我在Perl类中编写的代码,并且注意到了这一点。'@_'在Perl中做什么?

my ($string) = @_; 
my @stringarray = split(//, $string); 

我想知道两件事情: 第一行,其中变量是括号,这是宣告一个以上的变量时,你做的东西,如果我把他们赶走它仍然能工作吗?

第二个问题是@_做什么?

回答

21

@_变量是一个数组,其中包含传递给子例程的所有参数。

围绕$string变量的括号绝对必要。他们指定您正在从数组中分配变量。没有它们,@_阵列在标量上下文中被分配到$string,这意味着$string将等于传递给子例程的参数的数量。例如:

sub foo { 
    my $bar = @_; 
    print $bar; 
} 

foo('bar'); 

这里的输出是1 - 绝对不是你在这种情况下所期待的。

或者,你可以分配$string变量不使用@_阵列,通过shift函数:

sub foo { 
    my $bar = shift; 
    print $bar; 
} 

使用一种方法比另一种是味道真有那么回事。如果你有兴趣,我问了这个问题which you can check out

5

变量@_是一个数组(因此前缀为@),它将所有参数保存到当前函数中。

9

Perl有两种​​不同的上下文,标量上下文和列表上下文。数组'@_',如果在标量上下文中使用,则返回数组的大小。

因此,给出这两个例子,第一个例子给出了@_  数组的大小,另一个给出了第一个元素。

my $string = @_ ; 
my ($string) = @_ ; 

Perl有三个 '默认' 变量$_@_,取决于你问%_谁。如果你不给它们一个变量来处理,许多操作将使用这些变量。唯一的例外是没有操作,目前默认使用%_

例如我们有push,pop,shiftunshift,所有人都会接受一个数组作为第一个参数。 如果你不给他们一个参数,他们将使用'默认'变量。所以'shift;'与'shift @_;'相同'

子程序的设计方式,你无法正式告诉编译器你想要哪些变量。那么只需使用'default'数组变量'@_'来保存参数是有意义的。

所以这三个子程序(几乎)完全相同。

sub myjoin{ 
    my ($stringl, $stringr) = @_; 
    return "$stringl$stringr"; 
} 

sub myjoin{ 
    my $stringl = shift; 
    my $stringr = shift; 
    return "$stringl$stringr"; 
} 

sub myjoin{ 
    my $stringl = shift @_; 
    my $stringr = shift @_; 
    return "$stringl$stringr"; 
} 

我第一个想到的就是比其他两个稍快,因为你不修改@_变量。

+0

回复良好。然而,我不认为%_曾经在Perl中使用过。 (我的意思是,它从来没有假设,它不是任何其他类型的特殊变量,用户当然可以使用它,但他们甚至不会通过键入来保存任何键击,例如“keys”而不是“keys%_” “) – 2009-01-17 05:41:15

11

当您在Perl中遇到特殊(或标点符号)变量时,请查看the perlvar documentation。它列出它们全部,给你一个English等价物,并告诉你它做了什么。