大多数人终生追逐的那些希望和努力是毫无价值的。每个人只是因为有个胃,就注定要参与这种追逐。而且由于参与这种追逐,他的胃是可能得到满足的,但是,一个有思想、有感情的人却不能由此得到满足。——爱因斯坦

Perl 引用与匿名数组

写这篇是因为工作遇到一个需要使用列表作为hash的值的问题,这在Python中是非常简单而轻松的事,如下面这段python程序。

1 def add_to_index(index, keyword, url):
2         if keyword in index:
3         index[keyword].append(url)
4     else:
5         index[keyword] = [url]

但在Perl中怎么办呢?答案是使用引用,同样轻松搞定。

创建引用

1.使用\操作符

#标量引用
my$scalar=42;
my$sref=\$scalar ;

# 数组引用
my@array= (1,2,3) ;
my$aref=\@array ;

#哈希引用
my%hash= ("name"=>"foo","age"=>42,"gender"=>"male") ;
my$href=\%hash ;

#子程序引用
sub handler {return 1}
$coderef   = \&handler;

#句柄引用
$globref   = \*STDOUT;

其中,句柄引用有什么用?

 

2.匿名引用

 定义一个普通数组: my @a = (1,2,3);

 定义一个匿名数组引用: my $a = [1,2,3];

 定义一个以匿名数组引用为元素的数组(实际是二维数组):

@a = (
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
)

其中:$a[1][2]表示第二行第三列元素6.

定义一个以匿名数组引用为元素的数组引用(实际是二维数组的引用):

my $aref = [1, [2, 3], [4, 5, 6]] ;
print $aref->[0] , "\n" ; #1
print $aref->[1][1], "\n" ; #3
print $aref->[2][0], "\n" ; #4

注意:

  • 前者是真正的数组,所以定义变量是使用@,后者是指向匿名数组的引用,所以定义的时候使用$
  • 前者的数组元素是匿名数组,而外层数组则是实体数组,后者无论元素还是外层数组都是匿名数组
  • 前者可以用$a[x][y]的形式访问,而后者只能用解引用的方式访问,即$a->[x][y]的形式。

 

 定义一个普通hash: my %h = (a=>1,b=>2,c=>3); #注意是小括号,不是大括号, 否则会报 Reference found where even-sized list expected at ...

 定义一个匿名hash引用: my $h = {a=>1, b=>2, c=>3} #注意是大括号

 注意: 匿名数组/hash的元素仍然可以是匿名数组/hash,所以我们可以用这种方法构造多维数组/hash: 

 

1 my $a = [
2         [1, 2, 3],
3         [4, 5, 6],
4         [7, 8, 9],
5 ]
 1 my $h= {
 2     'a' => {
 3         'x' => 1,
 4         'y' => 2,
 5         'z' => 3,
 6     },
 7 
 8     'b' => {
 9         'u' => '4',
10         'v' => '5',
11         'w' => '6',
12     }
13 } ;

 

 

使用引用

使用引用并不难,只要把引用的值当做原型的名字使用即可.

比如aref是一个数组引用,对应a是数组, 我们可以把$aref整体当做数组的名字a,因此要获取数组的值即: ${$a}[0], ${$a}[1]

遵循这个原则就很容易了.

 1 my $s = 1 ;
 2 my @a = (1, 2, 3) ;
 3 my %h = ('a' => 1, 'b' => 2) ;
 4 
 5 my $sref = \$s;  
 6 my $aref = \@a;
 7 my $href = \%h;
 8 
 9 print $$sref, "\n" ;
10 print @$aref, "\n" ;
11 print %$href, "\n" ;
12 print $$aref[2], "\n" ;
13 print $$href{'a'}, "\n" ;

注意:当{}内部是$var的形式时,{}是可以省略的,也就是说@{$aref}等价于@$aref,不过初学最好养成使用{}的习惯。

 

Reference

http://www.cnblogs.com/softwaretesting/archive/2011/07/26/2117730.html

posted @ 2015-12-01 09:33  东去春来  阅读(1585)  评论(0编辑  收藏  举报