修改子程序参数(Perl)

时间:2015-01-06 10:07:30

标签: perl parameters subroutine

我想编写一个Perl子例程first,它将列表作为输入,返回列表中的第一个元素并从列表中删除第一个元素。

像这样:

@list = (1,2,3);
print first(@list); // 1
print @list; // 23

这不太合适:

sub first(@) {
    return shift @_;
}

我得到的是:

print first(@list); // 1
print @list; // 123

堆栈变量@_改变了我期望它的方式(首先它是(1, 2, 3)然后它是(2, 3)),但我给出的列表作为输入(@list)是没有改变。我认为堆栈变量保存了对它引用的变量的引用。

当我更改子例程中的列表元素时,它也会更改@list中的某些内容,但不会更改我想要的内容,但是那个+ 1。所以,如果我在子例程中写入:

@_[0] = "X";

执行子程序print @list后,我会得到2X6

2 个答案:

答案 0 :(得分:2)

您需要在@原型前面添加斜杠以获取数组引用,然后修改引用。如果您只使用@,您将在子例程中获得数组@list的副本(因此不会修改父类中的数组)。来自http://perldoc.perl.org/perlsub.html#Prototypes

  

Unbackslashed原型字符具有特殊含义。任何   unbackslashed @或%吃掉所有剩余的参数,并强制列表   上下文。

所以你可以写:

use strict;
use warnings;

sub first (\@) {
    my $a = shift;
    return shift @$a;
}

my @list = (1,2,3);
print first(@list) . "\n"; 
print "@list" . "\n"; 

输出:

1
2 3

答案 1 :(得分:1)

你没有列表,你有阵列。 Perl中的数组和列表是不同的(正如great blog post解释的那样)。如果您有一个名为@list的数组,那么您只是保证让自己(以及将来维护您的代码的人)感到困惑。