Perl:如何在不创建数组副本的情况下取消引用数组?

Dem*_*Imp 1 arrays perl function subroutine dereference

当我使用@ $ arrayRef或@ {$ arrayRef}取消引用数组时,它似乎创建了数组的副本.是否有正确的方法来取消引用数组?

这段代码......

sub updateArray1 {
        my $aRef = shift;
        my @a = @$aRef;
        my $aRef2 = \@a;

        $a[0] = 0;
        push(@a, 3);
        my $aRef3 = \@a;

        print "inside1 \@a: @a\n";
        print "inside1 \$aRef: $aRef\n";
        print "inside1 \$aRef2: $aRef2\n";
        print "inside1 \$aRef3: $aRef3\n\n";
}

my @array = (1, 2);

print "before: @array\n";
my $ar = \@array;
print "before: $ar\n\n";

updateArray1(\@array);

print "after: @array\n";
$ar = \@array;
print "after: $ar\n\n";
Run Code Online (Sandbox Code Playgroud)

......有输出......

before: 1 2
before: ARRAY(0x1601440)

inside1 @a: 0 2 3
inside1 $aRef: ARRAY(0x1601440)
inside1 $aRef2: ARRAY(0x30c1f08)
inside1 $aRef3: ARRAY(0x30c1f08)

after: 1 2
after: ARRAY(0x1601440)
Run Code Online (Sandbox Code Playgroud)

如您所见,@ $ aRef创建一个新的指针地址.

我发现解决这个问题的唯一方法是仅使用引用:

sub updateArray2 {
        my $aRef = shift;

        @$aRef[0] = 0;
        push(@$aRef, 3);

        print "inside2 \@\$aRef: @$aRef\n";
        print "inside2 \$aRef: $aRef\n\n";
}

updateArray2(\@array);

print "after2: @array\n";
$ar = \@array;
print "after2: $ar\n\n";
Run Code Online (Sandbox Code Playgroud)

产生输出:

inside2 @$aRef: 0 2 3
inside2 $aRef: ARRAY(0x1601440)

after2: 0 2 3
after2: ARRAY(0x1601440)
Run Code Online (Sandbox Code Playgroud)

是否有可能取消引用指向数组的指针而不会使整个数组重复?或者我是否需要将其保留在参考表格中并在我想要使用它时取消引用它?

Ste*_*ich 10

取消引用不会创建副本,如以下示例所示:

my @a = qw(a b c);
my $ra = \@a;
@{$ra}[0,1] = qw(foo bar);  # dereferencing is done here but not copying
print @$ra; # foo bar c
print @a; # foo bar c
Run Code Online (Sandbox Code Playgroud)

相反,将(解除引用的)数组分配给另一个数组会创建副本:

my @a = qw(a b c);
my $ra = \@a;
my @newa = @$ra;   # copy by assigning
$newa[0] = 'foo';
print @newa; # foo b c
print @a; # a b c
Run Code Online (Sandbox Code Playgroud)

将一个数组分配给另一个数组基本上说,旧数组中的所有元素也应该分配给新数组 - 这与原始数组的名称不同.但是将一个数组引用分配给另一个数组引用只会使旧数组具有不同的名称,即复制数组引用与复制数组内容.

请注意,这似乎与Python或Java等语言不同,因为在这些语言中,变量仅描述数组对象,即对数组的引用,而不是数组的内容.


yst*_*sth 5

使用实验性的重新混叠功能:

use 5.022;
use warnings;
use feature 'refaliasing';
no warnings 'experimental::refaliasing';
\my @array = $array_ref;
Run Code Online (Sandbox Code Playgroud)

但为什么不把它作为参考呢?没有什么可以对数组做的,而不能对数组引用做的。