引用是指向数据项,反引用是访问它所指向的实际数据项。 引用和内存中的数据项地址非常的类似,通过使用地址可 以直接访问数据项。perl中有两种类型的引用:直接引用 和符号引用。
我们一般都会按照名称来引用数据项,而让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: $first = 5; 2: $ref = "first"; 3: print "$$ref\n"; 4: #上面输出'5' 5: @a=(1,2,3); 6: $ref_a="a"; 7: print "@$ref_a\n"; 8: #上面输出1 2 3
现在我们看到符号引用的工作方式了,按照名称,而不是按照 内存位置(记住,名称,并不包含任何前缀反引用符号)
箭头运算符号,是非常重要的运算符号(称为中缀反引用运算符) 也是一个流行的反引用运算符。
1: @array = (1,2,3); 2: $ref = \@array; 3: print " @$ref[0]\n"; 4: print " $ref->[0]"; 5: #结果是一样的都是1 6:
perl的强大功能之一就是可以使用数组、哈希表和子程序 的引用,而不是名称来创建那些结构。也就是说需要存储 的是对他们的引用,而不是名称。
1: $arrayref=[1,2,3]; 2: print $$arrayref[0]; 3: #1 4: #变量$arrayref存储了对数组的引用,而不是对新数组的名称 5: #可以按照名称或者按照位置来引用数据项,上面就是对这种想法 6: #的合理延伸,另外,可以创建仅有引用来标示的数据项。 7:
可以用反斜杠\运算符来创建之间引用,可以在标量、数组 hash、子程序或者简单值上使用反斜杠运算符。
1: $ref = \ "Hello"; 2: print $$ref; 3: #Hello 4: #这种方法的嵌套深度任意 5: $ref=\\\\ "Hello"; 6: print $$$$$ref; 7: #Hello 8:
1: #对标量的引用 2: $first = 100; 3: $ref_first = \$first; 4: print "$$ref_first\n"; 5: #100 6: 7: #对数组的引用 8: @second = (1,2,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:
假设某个引用存在,在进行了反引用操作,则那个引用自动生成,
1: $$ref=5; 2: print "$$ref\n"; 3: print "$ref\n"; 4:
引用的最大用途之一就是向子程序传递数组和hash表。如果直接传递数组或者 hash,则他们将一起展开到@中。\\ 下面这个程序将对两个数组的引用传递给子程序,这个例子将对两个数组的引用 传递给子程序,这个子程序将数组中对应的元素相加,并返回产生的数组,向子 程序传递引用而不是传递数组本身,就避免将数组展开到无法区分的长列表中:
1: @a = (1,2,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);
使用方括号,可创建无名称数组,也就是匿名数组
1: $array_ref = [1,3,4]; 2: print $$array_ref[0]; 3: #1 4: #也可以使用箭头运算符来反引用数组运算符号 5: $array_ref = [1,3,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,2,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,2,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
一个问题,如果考虑到每一个细节,那么可能费的时间是现在的很多倍,所以记录下这些 常用的功能,然后后面的在后面再学习。本内容参考的是《perl技术内幕》这本书。表示感谢!
Date: 2013-05-26 11:46:41 CST
HTML generated by org-mode 6.33x in emacs 23