Perl: 数组引用与匿名数组

8
这可能是一个愚蠢的问题...以下代码分别输出@arrayref@arraycont的内容。请注意它们之间的区别以及它们的值被赋值的方式。我知道匿名数组是什么,但有人能解释一下为什么会有差异吗?
非常感谢。
@arrayref = ();
@array = qw(1 2 3 4);
$arrayref[0] = \@array;
@array = qw(5 6 7 8);
$arrayref[1] = \@array;
print join "\t", @{$arrayref[0]}, "\n";
print join "\t", @{$arrayref[1]}, "\n";

@arraycont = ();
@array = qw(1 2 3 4);
$arraycont[0] = [@array];
@array = qw(5 6 7 8);
$arraycont[1] = [@array];
print join "\t", @{$arraycont[0]}, "\n";
print join "\t", @{$arraycont[1]}, "\n";

输出

5   6   7   8   
5   6   7   8   
1   2   3   4   
5   6   7   8   
3个回答

11

这将创建一个数组的浅拷贝:

$arraycont[0] = [@array];

而这只是创建对其的引用:

$arrayref[0] = \@array;

由于您稍后修改了数组:

@array = qw(5 6 7 8);

arrayref 仍然指向相同的内存位置,因此在打印语句中取消引用时,它会打印当前数组值 5 6 7 8


1
一个浅拷贝,如果@array包含引用,则[@array]将包含相同的引用。在这种情况下,深度/浅度差异不适用,但我认为值得一提。 - mu is too short

3
第一个块存储了@array的地址。引用就像'直播',你可以得到当前状态。 因此,如果你创建一个对@array的引用,比如\@array,当你解引用时,你总是会得到@array在解引用时所指向的内容。 当你解引用@array时,它是有(5 6 7 8)的值。
当你执行[@array]时,就像将直播记录到你的磁盘中。因此,当你(重新)播放已记录的内容时,你会得到录制时@array的内容。因此,当你引用$arraycont[0]时,你会得到@array在复制时的内容,即
(1 2 3 4)

0

你在$arrayref[0]$arrayref[1]中都存储了对同一个数组的引用。你应该使用不同的数组。

my @refs;

my @array1 = qw(1 2 3 4);
push @refs, \@array1;

my @array2 = qw(5 6 7 8);
push @refs, \@array2;

在实践中,my 在循环的每一次通过中执行,每次都创建一个新的数组。
my @refs;
while ( my @row = get() ) {
   push @refs, \@row;
}

在极少数情况下,您需要克隆一个数组,您可以使用以下代码:
use Storable qw( dclone );

push @refs, [ @row ];       # Shallow clone
push @refs, dclone(\@row);  # Deep clone

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