为什么 Perl 有时会回收引用?

Lon*_*TP5 2 arrays perl reference

以下代码:

use strict;
use warnings;

my @array = (0,1,2,3,4,5,6,7,8,9);
print "array ref is ".\@array."\n";

my @copy_refs;
for my $element(@array) {
    my @copy = @array;
    print "copy ref is ".\@copy."\n";
    push @copy_refs, \@copy;
}
Run Code Online (Sandbox Code Playgroud)

产生以下输出,正如人们所期望的:

array ref is ARRAY(0x21ae640)
copy ref is ARRAY(0x21e2a00)
copy ref is ARRAY(0x21d7368)
copy ref is ARRAY(0x21d71e8)
copy ref is ARRAY(0x21d70c8)
copy ref is ARRAY(0x21d6fa8)
copy ref is ARRAY(0x21d6e88)
copy ref is ARRAY(0x21d6d68)
copy ref is ARRAY(0x21d6c48)
copy ref is ARRAY(0x21cf8a0)
copy ref is ARRAY(0x21cf780)
Run Code Online (Sandbox Code Playgroud)

但是,相同的代码,push @copy_refs, \@copy;删除后,会产生以下输出:

array ref is ARRAY(0x229e640)
copy ref is ARRAY(0x22d2a00)
copy ref is ARRAY(0x22d2a00)
copy ref is ARRAY(0x22d2a00)
copy ref is ARRAY(0x22d2a00)
copy ref is ARRAY(0x22d2a00)
copy ref is ARRAY(0x22d2a00)
copy ref is ARRAY(0x22d2a00)
copy ref is ARRAY(0x22d2a00)
copy ref is ARRAY(0x22d2a00)
copy ref is ARRAY(0x22d2a00)
Run Code Online (Sandbox Code Playgroud)

为什么是这样?

ike*_*ami 6

Perl 使用引用计数来确定何时释放变量。一旦没有引用变量,变量就会被释放。当变量在作用域内时,代码块(例如,子文件和文件)维护对其中声明的词法变量的引用,因此变量通常在作用域退出时被释放。

换句话说,my @copy分配一个新数组。当范围退出时,@copy如果没有其他内容引用它,则会被释放。

当你这样做时push @copy_refs, \@copy;@copy_refs引用数组,所以@copy不会被释放。

当你省略时push @copy_refs, \@copy;,没有任何引用@copy,所以它被释放了。这使得内存可在下一次循环中重复使用。

有点。

作为一种优化,如果在变量超出范围时没有任何引用变量,它只会被清除而不是被销毁和重新创建。所以@copy不仅仅是在同一位置重新分配;它实际上与已清除的数组完全相同。