第一章 数据引用与匿名存储

来源:互联网 发布:网络媒介素养 名词解释 编辑:程序博客网 时间:2024/06/04 18:55
数据引用与匿名存储:1.不必使用变量名就能够动态地位数据分配存储空间,我们称之为匿名数据结构2.可以指向任何数据结构,无论它是静态分配还是动态分配的Perl的引用同样可以指向常规数据类型(如标量变量,数组和散列表)和其他类型的实体。比如下面这行代码:[root@node01 1]# cat a1.pl use Data::Dumper;$line[19]="hello";print @line;print "\n";print Dumper(@line);print "\n";[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语言中要花费很多行的diamantePerl将确保一块数据当且仅当没有任何引用的情况下才被释放(这就确保了内存泄露不会发生)[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 "\n";print $rarray;print "\n";print $rhash;print "\n";[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 "\n";[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 "\n";[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 "\n";[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\n";$rarray=\@array;push (@$rarray,1,2,3,);print "\@array=@array\n";[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\n";  print "\@arr2 =@arr2\n";};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\n";print "\@array2=@array2\n";sub AddArrays {   my ($rarray1,$rarray2) =@_;   $len2=@$rarray2;#array2的长度   for ($i=0;$i<$len2;$i++){    $rarray1->[$i] += $rarray2->[$i];    print "\$rarray1->[$i]=$rarray1->[$i]\n";};};[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 "\n";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 "\n";print $sue{'children'};print "\n";print @{$sue{'children'}};print "\n";foreach (@{$sue{'children'}}){print %{$_};print "\n";};print  $sue{'children'}->[0]->{'name'};[root@node01 1]# perl a11.pl nameSuechildrenARRAY(0xafa168)age45ARRAY(0xafa168)HASH(0xaedc90)HASH(0xaedd38)age20nameJohnage16namePeggyJohn[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 "\n";print $sue{'children'};print "\n";print @{$sue{'children'}};print "\n";foreach (@{$sue{'children'}}){print %{$_};print "\n";};print  $sue{'children'}->[0]->{'name'};print "\n";print  $sue{'children'}[0]{'name'};print "\n";[root@node01 1]# perl a11.pl age45childrenARRAY(0x1d9a1a8)nameSueARRAY(0x1d9a1a8)HASH(0x1d8dc90)HASH(0x1d8dd38)nameJohnage20age16namePeggyJohnJohn谈到程序员的效率,让我们谈论一个节省键盘敲击次数的技巧。在两个下标之间(也只有在下标之间)你可以省去箭头符号"->"你会看到即便是如此简单的例子,也更多的得益于匿名的数组和散列表,而不是有名的数组和散列表。[root@node01 1]# cat a12.pl %sue = (    'name' =>'Sue',    'age'=>'45',    'children'=>[                  {     'name'=>'John',     'age'=>'20'     },     {       'name' => 'Peggy',       'age'=>'16'     }     ]);  print %sue;print "\n";   [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 "\n";   print $sue{children}->[1]->{age};[root@node01 1]# perl a12.pl age45childrenARRAY(0x159c540)nameSue16[root@node01 1]# 引用的查询:ref 函数被用来查询标量变量是否包含一个引用,是的话,再判定所指向的是什么数据的类型[root@node01 1]# cat a13.pl my $a="123";print ref($a);print "\n";print "-------------\n";my $ra=\$a;print ref($ra);print "\n";[root@node01 1]# perl a13.pl -------------SCAL符号引用:


                                             
0 0
原创粉丝点击