我想编写一个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
。
答案 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
的数组,那么您只是保证让自己(以及将来维护您的代码的人)感到困惑。