我该如何将两个列表传递给Perl子例程?

5
在Perl中,是否可以将两个列表传递给sub?例如:
sub Foo {
 my(@list1,@list2) = @_;

}

我知道我可以创建两个列表,每个子列表都是所需的参数,我只是想知道是否有更简洁的方法。

2个回答

10

如果你想要两个数组,你可以使用一个原型:

sub foo (\@\@) {
   my $arr1 = shift;
   my $arr2 = shift;

   # Access arrays as references
}

foo( @wiz, @waz );  # @wiz and @waz won't be flattened.

但是有很多方法可以绕过原型,我更喜欢在大多数情况下避免使用它们。您可以简单地跳过原型并手动传递引用:

sub foo {
   my $arr1 = shift;
   my $arr2 = shift;

   # Access arrays as references
}

foo( \@wiz, \@waz ); # Pass in wiz/waz as refs
foo( [1,2,4],[3,5,6] );  # Hard coded arrays

如果你从来没有使用过引用,请查看perlreftut,这是一个不错的教程。


14
@Mike,我建议不要使用原型,因为有经验的Perl程序员会对它们感到更意外,而不是需要传递引用的要求。请查看https://dev59.com/lXVC5IYBdhLWcg3wbghT以了解有关原型为何不受欢迎的更多信息。 - daotoad
4
确实,最好避免使用原型。如果您尝试将一个被原型化的子程序作为对象方法调用,可能会得到意外的结果。 - Ether
2
当你试图传递一个内联生成的值而没有中间数组(例如 mapgrep 的输出)时,引用原型可能有点麻烦。然而,非引用原型可以非常有用。后者 foo 的示例也可以这样调用:foo \\(@wiz, @waz) - Eric Strom
你有一个非常糟糕的习惯,就是把错误的答案放在第一位(甚至还特别提到它)。 - brian d foy
@brian d foy => 将匿名数组传递给带有 (\@) 原型的函数是语法错误。它需要是 @{[ map {} ... ]} ... 这最终并没有提高可读性,只是在解析器无法理解的完全明确的情况下工作。 - Eric Strom
显示剩余4条评论

5
如果您通过值传递两个列表...您将得到一个大列表@_my(@list1,@list2) = @_;没有任何意义。
#!/usr/bin/perl

sub test
{
    my (@a, @b) = @_;

    print "@a\n";
    print "@b\n";
}

my @array1 = (1,2,3);
my @array2 = (5,6,7);

test(@array1, @array2);

这将打印出以下内容:
1 2 3 5 6 7
<blank line> 

要传递两个数组,您需要通过引用传递它们:

test(\@array1, \@array2);

在您的子程序中,您需要将它们视为引用:

sub test
{
    my ($arrayRef1, $arrayRef2) = @_;
    print "@$arrayRef1\n";
    print "@$arrayRef2\n";
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接