第八章,引用: [root@wx03 2]# cat a7.pl @john = (47, "brown", 186); @mary = (23, "hazel", 128); @bill = (35, "blue", 157); @vitals = ('john', 'mary', 'bill'); print $vitals[0][1]; print " "; [root@wx03 2]# perl a7.pl brown [root@wx03 2]# cat a8.pl @vitals=([47,"brown",186],[23, "hazel", 128],[35, "blue", 157]); print $vitals[0][1]; [root@wx03 2]# perl a8.pl brown[root@wx03 2]# [root@wx03 2]# 在本章的术语里,引用一个数值就是创建一个指向它的硬引用。 有两个内建的函 数,bless 和 block,它们都接受一个引用 作为自己的参数 8.2.1 反斜杠操作符 $scalarref = $foo; $constref = 186_282.42; $arrayref = @ARGV; $hashref = \%ENV; $coderef = &handler; $globref = *STDOUT; 8.2.2.1 匿名数组组合器 你可以用方括弧创建一个创建一个指向匿名数组的引用: [root@wx03 2]# cat a9.pl $arrayref = [1, 2, ['a', 'b', 'c', 'd']]; print $arrayref->[2][1]; print " "; print $arrayref->[2]->[1]; print " "; [root@wx03 2]# perl a9.pl b b [root@wx03 2]# perl a9.pl b b 8.2.2.2 匿名散列组合器 [root@wx03 3]# cat a1.pl $table = { "john" => [47, "brown", 186], "mary" => [23, "hazel", 128], "bill" => [35, "blue", 157], }; print $table->{john}[1]; [root@wx03 3]# perl a1.pl brown[root@wx03 3]# 8.2.2.3 匿名子过程组合器 [root@wx03 3]# cat a2.pl $coderef = sub { print "Boink! " }; &$coderef ; [root@wx03 3]# perl a2.pl Boink! 8.2.3 对象构造器 特别是那些叫构造器的特殊子过程创建并返回指向对象的引用。对象 只是一种特殊的引用, 这些构造器是通过使用 bless 操作符,将一个普 通的引用物转换成一个对象实现的,所以我们可以 认为对象是一个赐过福的引用。 构造器可以用下列任何方法调用: $objref = Doggie::->new(Tail => 'short', Ears => 'long'); #1 $objref = new Doggie:: Tail => 'short', Ears => 'long'; #2 $objref = Doggie->new(Tail => 'short', Ears => 'long'); #3 $objref = new Doggie Tail => 'short', Ears => 'long'; #4 8.3 使用硬引用 8.3.2 把一个 BLOCK 块当作变量名用 8.3.3 使用箭头操作符 对于指向数组,散列,或者子过程的引用,第三种解引用的方法涉及到使用-> 操作符 print $array[3]->{"English"}->[0]; @array 第4个元素的下表为English的第1个元素 [root@wx03 3]# cat a4.pl $array=[1,2,3,{English=>['a','b','c','d9999']}]; print $array->[3]->{English}->[3] [root@wx03 3]# perl a4.pl d9999[root@wx03 3]# 请注意 $array[3] 和 $array->[3] 是不一样的。第一个东西讲的是 @array 里的第四个元素, 而第二个东西讲 的是一个保存在 $array 里的数组(可能是匿名的数组)引用的第四个元素。 perl 解引用自定义函数: [root@wx03 3]# cat a3.pl sub fun1() { $a=shift; $b=shift; return $a + $b; }; $ref=&{fun1}; print $ref; print " "; print &$ref(3,4); print " "; print $ref->(3,4); print " "; [root@wx03 3]# perl a3.pl CODE(0x1aa2b30) 7 7 8.3.4 使用对象方法 8.3.5 伪散列 [root@wx03 3]# cat a5.pl $john = [ {age => 1, eyes => 2, weight => 789}, 47, "brown", 186 ]; print $john->[0]->{weight}; print " "; [root@wx03 3]# perl a5.pl 789 8.3.7 闭合(闭包) 我们早些时候谈到过用一个没有名字的 sub {} 创建匿名子过程。 [root@wx03 3]# cat a6.pl { my $critter = "camel"; $critterref = $critter; }; print "$critter is $critter "; print "$critterref is $critterref "; print $$critterref." "; [root@wx03 3]# perl a6.pl $critter is $critterref is SCALAR(0x1b26ae8) camel $$critterref 的数值仍将是“camel”,即使在离开闭合的花括弧之后 $critter 消失了也如此。 但是 $critterref 也 可以指向一个指向了 $critter 的子过程: [root@wx03 3]# cat a7.pl { my $critter = "camel"; $critterref = sub { return $critter }; }; print "$critter is $critter "; print "$critterref is $critterref "; print &$critterref; [root@wx03 3]# perl a7.pl $critter is $critterref is CODE(0x19f9160) camel[root@wx03 3]# 就意味着如果 你某一时刻在特定的词法范围定义了一个匿名函数,那么它就 假装自己是在那个范围里运行的,即使后面它又从该 范围之外调用。 Perl并不给对象方法提供引用,但是你可以使用闭合获取类似的效果。假设,你需要这么一个引用: 它不仅仅指向他代表的方法的子过程,而且它在调用的时候,还会在特定的对象上调用该方法。 8.5 花括弧,方括弧和引号 我们指出了 ${identifier} 是不被当作符号引用看待的。 8.5.2 垃圾收集,循环引用和弱引用