修改子程序参数(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
的数组,那么您肯定会混淆自己(以及将来维护您的代码的人)。
我想编写一个 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
的数组,那么您肯定会混淆自己(以及将来维护您的代码的人)。