- #!perl
-
use feature qw(say);
-
use strict;
-
my @skipper=qw(a b c d e);
-
my $ref=\@skipper;
-
my $ref_cp=$ref;
程序创建了一个数组@skipper,一个指向它的引用$ref,并复制了一次$ref到$ref_cp.
现在又3种不同的方式能访问到@skipper中的内容.分别是:
@skipper
@$ref
@$ref_cp
Perl使用引用计数来跟踪有多少种方法访问同一数据.包括原始的名字(skipper)和对数据的引用.
在这个例子中,数据的引用计数值是3.
可以随意删除对数据的引用,除非引用计数为0,否则Perl会一直维护内存中的数据,并可以通过其他的引用访问数据.
- #!perl
-
use feature qw(say);
-
use strict;
-
sub check{...}
-
my @skipper=qw(a b c d e);
-
my $ref=\@skipper;
-
my $ref_cp=$ref;
-
&check(\@skipper);
-
$ref=undef;
-
{
-
my $ref_ag=\@skipper;
-
}
-
#$ref_ag goes out of scope at this point
当直接使用数组的引用(\@skipper)作为参数调用子程序(check)时(第8行),Perl会在函数内构建一个新的指向@skipper的引用并存入@_.当子程序返回后,这个临时引用会被自动删除,@skipper中数据的引用计数值减1.
用户可以直接删除一个指向@skipper的引用,如第9行.
第11行的$ref_ag处于一个匿名代码块(code block)中,只在这个代码块中有效,当程序当前行移出代码块后(12行之后),$ref_ag失效.
只有在指向内存数据的所有引用(变量/数组/哈希名字,引用)都失效后,Perl才会回收相应的内存空间.但这些空间Perl保留下来,给后来的数据使用,而不会归还给操作系统.
- #!perl
-
use strict;
-
use 5.010;
-
my $ref;
-
{
-
my @array=qw(a b c d e);
-
$ref=\@array;
-
}
-
say "@$ref";
程序在匿名块中定义了数组@array,并用全局变量$ref存放数组的引用.在第9行,代码块中的数组名array失效,而相应数据的引用计数为1,因为还有全局变量$ref指向,所以数据在第9行还可以访问.可以说,$ref是一个匿名列表的引用.- #!perl
-
use strict;
-
use 5.010;
-
sub fun{
-
my @array_1=qw(a b c d e);
-
my @array_2=qw(1 2 3 4 5);
-
return(\@array_1,\@array_2);
-
}
-
my @all=&fun();
-
for(@all) {
-
say "@$_";
-
}
同样的,在这个程序中,即使子程序返回后使得数组名array_1和array_2失效,但因为在@all中存有对应数据(列表)的引用,所以数据还是可以访问(第10~12行),即@all中存有两个指向匿名列表的引用.
阅读(416) | 评论(0) | 转发(0) |