Perl中的'@_'是什么意思?

12

我正在浏览我在 Perl 课程中编写的一些代码,然后我注意到了这个。

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

我有两个问题: 第一行括号中的变量,这是在声明多个变量时使用的,如果我删除它们,代码仍然可以正常工作,对吗?

第二个问题是@_是什么意思?

4个回答

24

@_变量是一个数组,它包含了传递给子程序的所有参数。

括号将$string变量括起来是绝对必要的。它们指定你正在从一个数组中分配变量。如果没有它们,@_数组将在标量上下文中被赋值给$string,这意味着$string将等于传递给子程序的参数数量。例如:

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

foo('bar');

这里的输出为1 -- 明显不是你在这种情况下期望的结果。

或者,你可以不使用@_数组来分配$string变量,而是使用shift函数:

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

使用其中一种方法比另一种更多是品味问题。如果您感兴趣,可以查看我提出的这个问题,请点击此处


12

在Perl中遇到特殊(或标点符号)变量时,请查看perlvar文档。它列出了所有这些变量,给出了对应的英文译名,并告诉你其作用。


10

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

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

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

Perl有三个“默认”变量$_@_和根据不同人的说法可能会使用的%_。如果您没有给它们一个变量来操作,许多操作将使用这些变量。唯一的例外是目前没有任何操作会默认使用%_

例如,我们有pushpopshiftunshift,它们都将接受一个数组作为第一个参数。如果您不给它们一个参数,它们将使用“默认”变量。因此,“shift;”与“shift @_;”相同。

子程序设计的方式是,您无法正式告诉编译器您想要哪些值在哪些变量中。使用“默认”数组变量@_来保存参数是有道理的。

所以这三个子程序(几乎)是相同的。

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";
}

我认为第一个比其他两个略快,因为你没有修改@_变量。


回复不错。然而我认为在 Perl 编程语言中从未使用过 %_,因为它既不是预设变量,也不属于任何其他类型的特殊变量。当然,用户可以使用它,但是通过输入例如“keys”而非“keys %_”并不能省略任何按键。 - A. Rex
我认为我从未遇到过任何默认使用%_的 Perl 内置功能,但它仍被视为默认变量之一。或者至少我记得在某个地方读到过这样的信息。 - Brad Gilbert
在perlvar中没有提到%_的任何信息。在我多年的perl专业实践中,我也没有在任何地方看到过它。 - Hynek -Pichi- Vychodil

6
变量@_是一个数组(因此带有@前缀),包含当前函数的所有参数。

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