数据引用与匿名存储:
1.不必使用变量名就能够动态地位数据分配存储空间,我们称之为匿名数据结构
2.可以指向任何数据结构,无论它是静态分配还是动态分配的
Perl的引用同样可以指向常规数据类型(如标量变量,数组和散列表)和其他类型的实体。
比如下面这行代码:
[root@node01 1]# cat a1.pl
use Data::Dumper;
$line[19]="hello";
print @line;
print "
";
print Dumper(@line);
print "
";
[root@node01 1]# perl a1.pl
hello
$VAR1 = undef;
$VAR2 = undef;
$VAR3 = undef;
$VAR4 = undef;
$VAR5 = undef;
$VAR6 = undef;
$VAR7 = undef;
$VAR8 = undef;
$VAR9 = undef;
$VAR10 = undef;
$VAR11 = undef;
$VAR12 = undef;
$VAR13 = undef;
$VAR14 = undef;
$VAR15 = undef;
$VAR16 = undef;
$VAR17 = undef;
$VAR18 = undef;
$VAR19 = undef;
$VAR20 = 'hello';
它创建了20个元素的数组,然后将最后一个元素复制为一个字符串。同样的工作在C语言中要花费很多行的diamante
Perl将确保一块数据当且仅当没有任何引用的情况下才被释放(这就确保了内存泄露不会发生)
[root@node01 1]# cat a2.pl
$a="mam mia";
@array=(10,20);
%hash=("laurel"=>"hardy","nick"=>"nora");
##现在创建对它们的引用
$ra=$a;
$rarray=@array;
$rhash=\%hash;
print $ra;
print "
";
print $rarray;
print "
";
print $rhash;
print "
";
[root@node01 1]# perl a2.pl
SCALAR(0x1d72be8)
ARRAY(0x1d72c30)
HASH(0x1d72cc0)
引用本身就是一种标量变量:
间接访问(dereference)的意思就是取得引用所指的变量的值:
在C语言中,如果p是一个指针,那么*p就表示p所指向的值。
在Perl中如果$r是一个引用,那么$$r,@$r或%$r分别$r所引用的数据类型
(标量变量,数组,散列表)获取的相应的值。
[root@node01 1]# cat a3.pl
$a="mam mia";
@array=(10,20);
##现在创建对它们的引用
$ra=$a;
$rarray=@array;
print %$rarray;
[root@node01 1]# perl a3.pl
Not a HASH reference at a3.pl line 9.
[root@node01 1]#
对标量变量的引用:
以下是包含有标量变量的表达式:
对数组的引用:
简明的箭头记号:
[root@node01 1]# cat a5.pl
my @array=(1,4,7,2,5,8);
$rarray=@array;
print $$rarray[2];
print "
";
[root@node01 1]# perl a5.pl
7
[root@node01 1]# cat a5.pl
my @array=(1,4,7,2,5,8);
$rarray=@array;
print $rarray->[2];
print "
";
[root@node01 1]# perl a5.pl
7
与数组类似,你可以通过使用->{}记号来存取散列表中的数据元素;
[root@node01 1]# cat a6.pl
my %hash=("a"=>"a11","b"=>"b11");
my $rhash=\%hash;
print $rhash->{"a"};
print "
";
[root@node01 1]# perl a6.pl
a11
不存在自动间接访问:
[root@node01 1]# perl a7.pl
push on reference is experimental at a7.pl line 3.
[root@node01 1]# cat a7.pl
my @array=('aa','bb','cc');
$rarray=@array;
push ($rarray,1,2,3,);
[root@node01 1]# perl a7.pl
push on reference is experimental at a7.pl line 3.
[root@node01 1]# cat a7.pl
my @array=('aa','bb','cc');
print "@array=@array
";
$rarray=@array;
push (@$rarray,1,2,3,);
print "@array=@array
";
[root@node01 1]# perl a7.pl
@array=aa bb cc
@array=aa bb cc 1 2 3
向子例程传递数组和散列表:
当你要向子例程中传递一个以上的数组或散列表时,Perl将会把它们合并到@_数据中供子例程使用。
[root@node01 1]# cat a8.pl
sub fun1 {
my (@arr1,@arr2)=@_;
print "@arr1 =@arr1
";
print "@arr2 =@arr2
";
};
fun1((1,2,3),(4,5,6));
[root@node01 1]# perl a8.pl
@arr1 =1 2 3 4 5 6
@arr2 =
Perl 将会把它们合并到@_数组中供子例程使用。
唯一避免合并的方法就是传输输入数组或散列表的引用。
[root@node01 1]# cat a9.pl
@array1=(1,2,3);
@array2=(4,5,6,7);
AddArrays (@array1,@array2); #以引用方式传递数组
print "@array1=@array1
";
print "@array2=@array2
";
sub AddArrays {
my ($rarray1,$rarray2) =@_;
$len2=@$rarray2;#array2的长度
for ($i=0;$i<$len2;$i++){
$rarray1->[$i] += $rarray2->[$i];
print "$rarray1->[$i]=$rarray1->[$i]
";
};
};
[root@node01 1]# perl a9.pl
$rarray1->[0]=5
$rarray1->[1]=7
$rarray1->[2]=9
$rarray1->[3]=7
@array1=5 7 9 7
@array2=4 5 6 7
[root@node01 1]#
匿名存储的引用:
到目前为止,我们学习创建了对已存在变量的引用,现在我们要学习对"匿名"数据结构的引用,
也就是那些没有同变量名关联的值。
创建匿名数组,需要使用方括号而不是圆括号,如:
$ra=[]; #创建一个空的匿名数组,并返回对它的引用
$ra=[1,"hello"];#创建一个经过初始化的匿名数组,并返回对它的引用
[root@node01 1]# cat a10.pl
use Data::Dumper;
$ra=[];
$ra=[1,"hello"];
print Dumper($ra);
print "
";
print @$ra;
[root@node01 1]# perl a10.pl
$VAR1 = [
1,
'hello'
];
多重引用的间接访问:
嵌套数据结构:
John[root@node01 1]# cat a11.pl
%sue =(
'name'=>'Sue',
'age'=>'45');
%john=(
'name'=>'John',
'age'=>'20'
);
%peggy=(
'name'=>'Peggy',
'age'=>'16');
@children=(\%john,\%peggy);
$sue{'children'}=@children;
print %sue;
print "
";
print $sue{'children'};
print "
";
print @{$sue{'children'}};
print "
";
foreach (@{$sue{'children'}}){
print %{$_};
print "
";
};
print $sue{'children'}->[0]->{'name'};
[root@node01 1]# perl a11.pl
nameSuechildrenARRAY(0xafa168)age45
ARRAY(0xafa168)
HASH(0xaedc90)HASH(0xaedd38)
age20nameJohn
age16namePeggy
John[root@node01 1]#
隐含的创建复杂的数据结构:
最后的缩写:省去两个下标间的箭头:
[root@node01 1]# cat a11.pl
%sue =(
'name'=>'Sue',
'age'=>'45');
%john=(
'name'=>'John',
'age'=>'20'
);
%peggy=(
'name'=>'Peggy',
'age'=>'16');
@children=(\%john,\%peggy);
$sue{'children'}=@children;
print %sue;
print "
";
print $sue{'children'};
print "
";
print @{$sue{'children'}};
print "
";
foreach (@{$sue{'children'}}){
print %{$_};
print "
";
};
print $sue{'children'}->[0]->{'name'};
print "
";
print $sue{'children'}[0]{'name'};
print "
";
[root@node01 1]# perl a11.pl
age45childrenARRAY(0x1d9a1a8)nameSue
ARRAY(0x1d9a1a8)
HASH(0x1d8dc90)HASH(0x1d8dd38)
nameJohnage20
age16namePeggy
John
John
谈到程序员的效率,让我们谈论一个节省键盘敲击次数的技巧。
在两个下标之间(也只有在下标之间)你可以省去箭头符号"->"
你会看到即便是如此简单的例子,也更多的得益于匿名的数组和散列表,
而不是有名的数组和散列表。
[root@node01 1]# cat a12.pl
%sue = (
'name' =>'Sue',
'age'=>'45',
'children'=>[
{
'name'=>'John',
'age'=>'20'
},
{
'name' => 'Peggy',
'age'=>'16'
}
]
);
print %sue;
print "
";
[root@node01 1]# perl a12.pl
age45childrenARRAY(0x124c540)nameSue
这段代码只有一个有名变量,子属性是一个指向匿名数组的引用,而数组的元素则又包含了指向
带有孩子详信息的匿名散列表。
[root@node01 1]# cat a12.pl
%sue = (
'name' =>'Sue',
'age'=>'45',
'children'=>[
{
'name'=>'John',
'age'=>'20'
},
{
'name' => 'Peggy',
'age'=>'16'
}
]
);
print %sue;
print "
";
print $sue{children}->[1]->{age};
[root@node01 1]# perl a12.pl
age45childrenARRAY(0x159c540)nameSue
16[root@node01 1]#
引用的查询:
ref 函数被用来查询标量变量是否包含一个引用,是的话,再判定所指向的是什么数据的类型
[root@node01 1]# cat a13.pl
my $a="123";
print ref($a);
print "
";
print "-------------
";
my $ra=$a;
print ref($ra);
print "
";
[root@node01 1]# perl a13.pl
-------------
SCAL
符号引用: