为什么引用的数组值没有改变?

时间:2017-12-07 10:06:53

标签: perl pass-by-reference

我正在尝试将数组的每个组件与标量相乘,为此,请尝试以下操作;

1 - )

@foo = (1, 2, 3, 5, 6);
vectorScalarMultiply(\@foo);
print @foo, "\n";

sub vectorScalarMultiply
{
    my $l_vectorRef = $_[0];
    for (my $var = 0; $var < scalar(@temp); $var++) {
        $l_vectorRef->[$var] = $l_vectorRef->[$var] * 5;
    }
}

1的输出;

  

12356

2 - )

@foo = (1, 2, 3, 5, 6);
vectorScalarMultiply(\@foo);
print @foo, "\n";
sub vectorScalarMultiply
{

    my $l_vectorRef = $_[0];
    map { $l_vectorRef->[$_] * 5 } { $l_vectorRef->[$_] };
}

2的输出;

  

123456

3 - )

@foo = (1, 2, 3, 5, 6);
@temp = @{$l_vectorRef};
vectorScalarMultiply(\@foo);
print @foo, "\n";
$l_vectorRef = map { $temp[$_] * 5; } @temp;

3的输出;

  

12356

我一直无法弄清问题是什么,为什么它们不起作用,所以我的主要问题是这些代码有什么问题?其次,怎么能我们解决了吗?

2 个答案:

答案 0 :(得分:7)

  1. 因为您忘记了use strict; use warnings;所以没有注意到@temp未定义,因此您的循环长度为0
  2. 因为您忘记了use strict; use warnings;所以没有注意到map { $l_vectorRef->[$_] * 5 } { $l_vectorRef->[$_] };期望{ $l_vectorRef->[$_] }成为列表。您也没有将map的结果分配到任何地方。
  3. 因为您忘记了use strict; use warnings;所以没有注意到您从未定义$l_vectorRef(但如果您这样做了,那么地图会覆盖参考而不是替换原始数组)

答案 1 :(得分:7)

第一个不起作用,因为你的循环条件是$var < scalar(@temp),但是没有@temp,所以循环永远不会执行。

第二个不起作用,因为map不会修改任何内容,并且您没有将map的结果分配给任何内容。

第三个不起作用,因为你正在修改sub中的变量$l_vectorRef,而修改该变量持有引用的数组。

这是一个更惯用的工作版本:

sub vectorScalarMultiply {
    my ($aref) = @_;
    $_ *= 5 for @$aref;
}