在Perl中分配多个数组子例程参数不起作用

时间:2014-04-21 10:40:59

标签: perl

我对此示例中的perl子例程参数感到困惑

当我在子程序参数中使用引用时,它可以工作:

@a = ( 1, 2 );
@b = ( 5, 8 );
@c = add_vecpair( \@a, \@b );
print "@c\n";
print $a[0];

sub add_vecpair {    # assumes both vectors the same length
    my ( $x, $y ) = @_;    # copy in the array references
    my @result;
    @$x[0] = 2;

    for ( my $i = 0; $i < @$x; $i++ ) {
        $result[$i] = $x->[$i] + $y->[$i];
    }

    return @result;
}

但是当我不使用引用作为这样的参数时:

@a = ( 1, 2 );
@b = ( 5, 8 );
@c = add_vecpair( @a, @b );
print "@c\n";
print $a[0];

sub add_vecpair {    # assumes both vectors the same length
    my ( @x, @y ) = @_;    # copy in the array references
    my @result;
    print @y;
    for ( my $i = 0; $i < @x; $i++ ) {
        $result[$i] = $x[$i] + $y[$i];
    }

    return @result;
}

..它不起作用。我什么时候需要使用引用作为子程序参数?

2 个答案:

答案 0 :(得分:5)

简短版本:问题在于这一行:

my (@x, @y) = @_; 

作业贪婪。首先处理@x,并从@_给出尽可能多的值。因为它可以处理所有这些,它最终得到@_的所有内容,而@y得不到。

结果与此相同:

my @x = @_;   # Gets all of the arguements
my @y;        # Gets nothing, and is therefore declared but uninitialized.

这就是为什么当子程序将多个值作为参数时,建议使用引用,并且这些值中至少有一个是数组或哈希值。


更长的版本: @_是传递给子例程的所有参数的组合,因此原始容器并不重要。请考虑下面的代码段。第一个是你的,第二个是完全相同的,但更清楚地显示正在发生的事情。

@a = (1, 2);
@b = (5, 8);
add_vecpair(@a,@b);

....与:

相同
add_vecpair(1, 2, 5, 8);

为了进一步解决问题,如果以这种方式处理,哈希变得非常混乱:

%a = ('a' => 1, 
      'b' => 2);
%b = ('c' => 3,
      'd' => 4);
somefunction(%a, %b);

...与:

相同
somefunction('a', 1, 'b', 2, 'c', 3, 'd', 4);

答案 1 :(得分:1)

当您使用数组或哈希参数调用Perl子例程时,它们将被展平为单个列表。因此,在第二种情况下,您的两个数组参数会失去其身份,而@_将成为包含@a@b元素的单个数组。