修改子程序参数(Perl)

Modify subroutine parameter (Perl)

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

像这样:

@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.

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

Unbackslashed prototype characters have special meanings. Any unbackslashed @ or % eats all remaining arguments, and forces list context.

所以你可以这样写:

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

你那里没有列表,你有数组。数组和列表在 Perl 中是不同的(正如 great blog post 解释的那样)。如果您有一个名为 @list 的数组,那么您肯定会混淆自己(以及将来维护您的代码的人)。