写这篇是因为工作遇到一个需要使用列表作为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