参数传递给 Perl 子例程的顺序重要吗?
Is the order in which parameters are passed to a Perl subroutine significant?
参数传递给 Perl 子程序的顺序重要吗?当我调试以下代码时:
my $loopCounter = 1;
foreach(@authors) {
my @splitAffiliations = splitAffiliations($params);
my @foundItems = findAffiliationForAuthor($_, @splitAffiliations, $loopCounter);
# Process @foundItems
$loopCounter++;
}
...
sub findAffiliationForAuthor {
my ($author, @affiliations, $aIndex) = @_;
...
}
我发现变量$loopCounter
在调用子例程findAffiliationForAuthor
之前有一个值,但在调用后未定义。因此,该子例程接收到前两个参数的值,而没有接收到第三个参数的值。但是,当我将参数的顺序更改为:
my @foundItems = findAffiliationForAuthor($loopCounter, $_, @splitAffiliations);
保留了$loopCounter
的值,按预期通过了子程序。
看来我必须将所有标量变量放在数组变量之前,或者不混合使用它们。听起来对吗?
当然顺序很重要。
参数按照您传递它们的顺序传递,数组参数被展平到参数列表中。参数列表作为 @_
列表的内容出现在子例程中。
您实际上不能将数组作为参数传递;它的元素被提取并与任何其他参数一起推入列表。
您遇到的问题是因为您处理参数的方式:
my ($author, @affiliations, $aIndex) = @_;
$author
按照您的预期获取 @_
的第一个元素,但 @affiliations
吞噬了列表的所有其余部分。然后将值 undef
存储在 $aIndex
.
中
您可以将 单个 数组传递给子例程,只要它是最后一个参数即可:
my($first_scalar, $second_scalar, @array) = @_;
如果将多个数组传递给子例程:
foo(@array1, @array2);
两个数组的元素被展平到一个列表中,子例程无法知道哪些元素来自哪个数组参数。
您可以将引用传递给数组:
sub foo {
my ($scalar1, $array_ref1, $scalar2, $array_ref2) = @_;
# ...
}
然后这样称呼它:
foo(42, \@array1, $some_scalar, \@array2);
子例程将标量列表作为参数。如果您从数组构建参数列表,则会传递数组的内容。
$ perl -E'sub f { say "$_: $_[$_]" for 0..$#_; } f("a", "b", "c", "d", "e")'
0: a
1: b
2: c
3: d
4: e
$ perl -E'sub f { say "$_: $_[$_]" for 0..$#_; } @a = ("b"); f("a", @a, "c", "d", "e")'
0: a
1: b
2: c
3: d
4: e
$ perl -E'sub f { say "$_: $_[$_]" for 0..$#_; } @a = ("b", "c"); f("a", @a, "d", "e")'
0: a
1: b
2: c
3: d
4: e
现在您将参数列表(@_
的内容)分配给
($author, @affiliations, $aIndex)
它应该分配多少个标量给 @affiliations
?你可以说除了第一个和最后一个之外的所有,但是你必须为
提出一个新规则
my (@a, @b) = @_;
为了简单起见,Perl 总是将所有剩余的标量分配给列表中的第一个数组。如果数组是最后一个元素,这可以正常工作,否则就不行。
如果要将数组传递给子对象,最好的方法是传递对它的引用。
$ perl -E'sub f { say "$_: $_[$_]" for 0..$#_; } @a = ("b", "c"); f("a", \@a, "d", "e")'
0: a
1: ARRAY(0x14ff8d0)
2: d
3: e
参数传递给 Perl 子程序的顺序重要吗?当我调试以下代码时:
my $loopCounter = 1;
foreach(@authors) {
my @splitAffiliations = splitAffiliations($params);
my @foundItems = findAffiliationForAuthor($_, @splitAffiliations, $loopCounter);
# Process @foundItems
$loopCounter++;
}
...
sub findAffiliationForAuthor {
my ($author, @affiliations, $aIndex) = @_;
...
}
我发现变量$loopCounter
在调用子例程findAffiliationForAuthor
之前有一个值,但在调用后未定义。因此,该子例程接收到前两个参数的值,而没有接收到第三个参数的值。但是,当我将参数的顺序更改为:
my @foundItems = findAffiliationForAuthor($loopCounter, $_, @splitAffiliations);
保留了$loopCounter
的值,按预期通过了子程序。
看来我必须将所有标量变量放在数组变量之前,或者不混合使用它们。听起来对吗?
当然顺序很重要。
参数按照您传递它们的顺序传递,数组参数被展平到参数列表中。参数列表作为 @_
列表的内容出现在子例程中。
您实际上不能将数组作为参数传递;它的元素被提取并与任何其他参数一起推入列表。
您遇到的问题是因为您处理参数的方式:
my ($author, @affiliations, $aIndex) = @_;
$author
按照您的预期获取 @_
的第一个元素,但 @affiliations
吞噬了列表的所有其余部分。然后将值 undef
存储在 $aIndex
.
您可以将 单个 数组传递给子例程,只要它是最后一个参数即可:
my($first_scalar, $second_scalar, @array) = @_;
如果将多个数组传递给子例程:
foo(@array1, @array2);
两个数组的元素被展平到一个列表中,子例程无法知道哪些元素来自哪个数组参数。
您可以将引用传递给数组:
sub foo {
my ($scalar1, $array_ref1, $scalar2, $array_ref2) = @_;
# ...
}
然后这样称呼它:
foo(42, \@array1, $some_scalar, \@array2);
子例程将标量列表作为参数。如果您从数组构建参数列表,则会传递数组的内容。
$ perl -E'sub f { say "$_: $_[$_]" for 0..$#_; } f("a", "b", "c", "d", "e")'
0: a
1: b
2: c
3: d
4: e
$ perl -E'sub f { say "$_: $_[$_]" for 0..$#_; } @a = ("b"); f("a", @a, "c", "d", "e")'
0: a
1: b
2: c
3: d
4: e
$ perl -E'sub f { say "$_: $_[$_]" for 0..$#_; } @a = ("b", "c"); f("a", @a, "d", "e")'
0: a
1: b
2: c
3: d
4: e
现在您将参数列表(@_
的内容)分配给
($author, @affiliations, $aIndex)
它应该分配多少个标量给 @affiliations
?你可以说除了第一个和最后一个之外的所有,但是你必须为
my (@a, @b) = @_;
为了简单起见,Perl 总是将所有剩余的标量分配给列表中的第一个数组。如果数组是最后一个元素,这可以正常工作,否则就不行。
如果要将数组传递给子对象,最好的方法是传递对它的引用。
$ perl -E'sub f { say "$_: $_[$_]" for 0..$#_; } @a = ("b", "c"); f("a", \@a, "d", "e")'
0: a
1: ARRAY(0x14ff8d0)
2: d
3: e