perl引用

1 深入分析

引用是指向数据项,反引用是访问它所指向的实际数据项。 引用和内存中的数据项地址非常的类似,通过使用地址可 以直接访问数据项。perl中有两种类型的引用:直接引用 和符号引用。

1.1 直接引用(hard reference)

我们一般都会按照名称来引用数据项,而让perl来处理具 体的数据项细节,但如果我们知道,或者能够得到数据项 的内存位置,那我么也可以通过位置来访问数据项.

1:  $first = 5;
2:  $ref   = \$first;
3:  print "$ref\n";
4:  print "$$ref\n";

在这里,$ref会输出一个地址,类似如<0X4c7cf0>,$ref 保存的是$first的引用(也就是$first的地址,数据类型 为标量)。这种类型的引用称为直接引用。
$$ref输出的是5,也就是$first本身。这里我们用了前缀 运算符($,@,%)来反引用,反引用提供了原始的数据值。
在这里我们可以解释,为什么$在perl中称为标量前缀反引用 符号,因为用它来反引用对标量的引用。
同样,对与@,%,&,我们也可以这样来用。

1:  @a = (1,2,3);
2:  $ref=\@a;
3:  print "@$ref\n";
4:  

1.2 符号引用(软引用)

符号引用并不保存数据项的地址和类型,而是保存数据项的名称 (记住,可以用两种方法引用数据,按名称或者按地址)

1:  $first = 5;
2:  $ref = "first";
3:  print "$$ref\n";
4:  #上面输出'5'
5:  @a=(1,3);
6:  $ref_a="a";
7:  print "@$ref_a\n";
8:  #上面输出1 2 3

现在我们看到符号引用的工作方式了,按照名称,而不是按照 内存位置(记住,名称,并不包含任何前缀反引用符号)

1.3 箭头运算符

箭头运算符号,是非常重要的运算符号(称为中缀反引用运算符) 也是一个流行的反引用运算符。

1:  @array = (1,3);
2:  $ref   = \@array;
3:  print " @$ref[0]\n";
4:  print " $ref->[0]";
5:  #结果是一样的都是1
6:   

1.4 匿名数组、hash表和子程序

perl的强大功能之一就是可以使用数组、哈希表和子程序 的引用,而不是名称来创建那些结构。也就是说需要存储 的是对他们的引用,而不是名称

1:  $arrayref=[1,3];
2:  print $$arrayref[0];
3:  #1
4:  #变量$arrayref存储了对数组的引用,而不是对新数组的名称
5:  #可以按照名称或者按照位置来引用数据项,上面就是对这种想法
6:  #的合理延伸,另外,可以创建仅有引用来标示的数据项。
7:  

2 快速解决方

2.1 创建直接引用

可以用反斜杠\运算符来创建之间引用,可以在标量、数组 hash、子程序或者简单值上使用反斜杠运算符。

1:  $ref = \ "Hello";
2:  print $$ref;
3:  #Hello
4:  #这种方法的嵌套深度任意
5:  $ref=\\\\ "Hello";
6:  print $$$$$ref;
7:  #Hello
8:  

2.1.1 对标量、数组、hash、子程序的引用

 1:  #对标量的引用
 2:  $first = 100;
 3:  $ref_first = \$first;
 4:  print "$$ref_first\n";
 5:  #100
 6:  
 7:  #对数组的引用
 8:  @second = (1,3);
 9:  $ref_second = \@second;
10:  print "@$ref_second\n";
11:  #1 2 3
12:  
13:  #对hash的引用
14:  %hash = (apple => fruit);
15:  $ref_hash = \%hash;
16:  print "$$ref_hash{apple}\n";
17:  #friut
18:  
19:  #第子程序的引用
20:  sub subroutine
21:  {
22:      print "Hello!\“;
23:  }
24:  $sub_ref = \&subroutine;
25:  &$sub_ref;
26:  

2.1.2 引用和自动生成

假设某个引用存在,在进行了反引用操作,则那个引用自动生成

1:  $$ref=5;
2:  print "$$ref\n";
3:  print "$ref\n"; 
4:  

2.1.3 按引用传递

引用的最大用途之一就是向子程序传递数组和hash表。如果直接传递数组或者 hash,则他们将一起展开到@中。\\ 下面这个程序将对两个数组的引用传递给子程序,这个例子将对两个数组的引用 传递给子程序,这个子程序将数组中对应的元素相加,并返回产生的数组,向子 程序传递引用而不是传递数组本身,就避免将数组展开到无法区分的长列表中:

 1:  @a = (1,3);
 2:  @b = (4,5,6);
 3:  
 4:  sub addem
 5:  {
 6:      my ($reference1,$reference2)=@_;
 7:      for ($loop_index = 0; $loop_index <= $#$reference1;$loop_index++)
 8:      {
 9:          $result[$loop_index] = @$reference1[$loop_index] +
10:                  @$reference2[$loop_index];
11:      }
12:      return @result;
13:  }
14:  @array = addem(\@a,\@b);
15:  print join (',',@array);

2.1.4 创建匿名数组的引用

使用方括号,可创建无名称数组,也就是匿名数组

1:  $array_ref = [1,3,4];
2:  print $$array_ref[0];
3:  #1
4:  #也可以使用箭头运算符来反引用数组运算符号
5:  $array_ref = [1,4];
6:  print $array_ref->[0];

匿名数组在很多方面都有作用,例如,可以使用匿名数组构成符来建立数组的副本, 以进行破坏性测试,而不会损害原来的数组。

1:  @a = (1,2,3);
2:  $s = pop @a;
3:  print "@a\n";
4:  #1 2
5:  #但是,如果用匿名数组构成符建立数组副本,则副本会发生变化,而原始数据保持不变
6:  @a = (1,3);
7:  $s = pop @{[@a]}
8:  print "@a\n";
9:  # 1 2 3

匿名数组提供了一种有用的方法,将子程序调用和或者表达式的结果插入到双引号 内的字符串中,

1:  print "@{[uc(hello)]} there.\n";
2:  #HELLO there.

perl 作为块来计算@{},而块在计算时将创建对匿名数组的引用。
如果想使用$#array的语法来着匿名数组的长度,只需要语法$#$来使用对匿名数组的引用。

1:  $ref = [1,3];
2:  for ($total = 0,$loop=0;$loop<=$#$ref+1;$loop++)
3:  {
4:      $total += $$ref[$loop];
5:  }
6:  print "Average value = ".$total / ($#$ref +1);
7:  #Average value = 2

3 结束

一个问题,如果考虑到每一个细节,那么可能费的时间是现在的很多倍,所以记录下这些 常用的功能,然后后面的在后面再学习。本内容参考的是《perl技术内幕》这本书。表示感谢!

Author: GRC <grc@grc>

Date: 2013-05-26 11:46:41 CST

HTML generated by org-mode 6.33x in emacs 23

相关文章

1. 如何去重 #!/usr/bin/perl use strict; my %hash; while(...
最近写了一个perl脚本,实现的功能是将表格中其中两列的数据...
表的数据字典格式如下:如果手动写MySQL建表语句,确认麻烦,...
巡检类工作经常会出具日报,最近在原有日报的基础上又新增了...
在实际生产环境中,常常需要从后台日志中截取报文,报文的形...
最近写的一个perl程序,通过关键词匹配统计其出现的频率,让...