为什么这些代码块的行为有所不同?

Evo*_*lor 0 perl pass-by-reference pass-by-value subroutine pass-by-pointer

我是Perl的新手,我无法弄清楚这一点.我有两组看似相同的代码,但是一个子程序更新了值而另一个没有.在第一组代码中,我的理解是传递对数组的引用,然后更新该引用指向的值.然后在离开子例程时,值已更改.但是,在第二个中,我希望发生同样的事情.它会更新数组,但在离开子程序后会忘记它.有人可以用第二套代码向我解释幕后发生的事情吗?

第一套代码:

#!/usr/bin/perl -w

use strict;

{
    my @array = (1, 2, 3);
    removeSecondElement(\@array);
    print @array;  #output: 13
    print("\n");
}

sub removeSecondElement{
    my ($arrayReference) = @_;
    splice(@$arrayReference, 1, 1);
    print @$arrayReference;  #output: 13
    print "\n";
}
Run Code Online (Sandbox Code Playgroud)

第二代码集:

#!/usr/bin/perl -w

use strict;

{
    my @array = (1, 2, 3);
    removeSecondElement(\@array);
    print @array;  #output: 123
    print("\n");
}

sub removeSecondElement{
    my ($arrayReference) = @_;
    my @array = @$arrayReference;
    splice(@array, 1, 1);
    print @array;  #output: 13
    print "\n";
}
Run Code Online (Sandbox Code Playgroud)

Que*_*tin 7

在第一个示例中,您使用引用来获取数组,然后进行修改.只有一个数组,您可以更改它.

在第二个示例中,您使用引用来获取数组,然后将数组的内容复制到第二个数组中,然后修改第二个数组.有两个数组,你永远不会改变原来的数组.

  • @Evorlor,是的,有两种方法.1)`我们的@alias; local*alias = $ ref;`2)`使用Data :: Alias; 别名我的@array = @ $ ref;`.但严重的是,习惯使用引用. (5认同)
  • @Evorlor:我很高兴你有解决方案,但请注意不要使用它的警告.创建别名是一个毫无意义的开销,许多人不会理解它. (4认同)
  • 并且第一种方式使用全局变量,这是你应该尽可能避免的.在这里,很容易直接使用引用而不是复制.如果你真的不能这样做,我会按原样使用你的第二个代码,但是添加`@ $ arrayReference = @array; 返回;`最后.(顺便说一句,你的子函数隐式返回任何打印返回;你应该总是在sub的末尾使用显式返回,甚至 - 或者特别是 - 如果它什么都不返回.) (4认同)