引用
引用一律聲明為標(biāo)量類型(即$開頭的命名變量),使用\運(yùn)算符取引用 對(duì)引用變量的修改等同于對(duì)引用指向?qū)嶋H數(shù)據(jù)的修改 取標(biāo)量變量引用:my $scalar_r = \$scalar; 取列表的引用:my $array_r = \@array; 取哈希的引用:my $hash_r = \%hash; 通過引用解決列表無法嵌套的問題: my @array1 = (10, 20, 30, 40, 50); my @array2 = ( 1, 2, \@array1, 3, 4);
因?yàn)閈@array1本質(zhì)上只是一個(gè)標(biāo)量,所以列表不會(huì)被扁平化,依舊保留了嵌套層次 對(duì)匿名列表的引用:將列表的()替換為[]:my $array_r = [1, 2, 3, 4, 5]; 對(duì)匿名哈希的引用:將哈希的()替換為{}:my $hash_r = { apple => "pomme", pear => "poire" }; 對(duì)引用變量解引用通過{$var_r}實(shí)現(xiàn) 列表 my @array = (1, 2, 3, 4, 5); my $array_r = \@array; my @array2 = @{$array_r}; #拷貝了數(shù)組
哈希與列表類似 對(duì)于數(shù)組引用,可以將${$ref}簡記為$ref->,例如可以將${$ref}[2]簡記為$ref->[2],而將${${ref}[2]}[1]簡記為$ref->[2]->[1],并進(jìn)一步簡記為$ref->[2][1] 使用undef銷毀一個(gè)引用:undef $ref; perl對(duì)于引用指向的數(shù)據(jù)維護(hù)一個(gè)引用計(jì)數(shù),當(dāng)計(jì)數(shù)減到0時(shí)引用指向的數(shù)據(jù)被銷毀,內(nèi)存空間被釋放 使用引用使得表示復(fù)雜的數(shù)據(jù)結(jié)構(gòu)成為可能。這些數(shù)據(jù)結(jié)構(gòu)包括矩陣(多維數(shù)組)、鏈表、樹、圖等。 一些思考:C/C++的引用主要為了傳地址。與C/C++中的指針、引用不同的是,perl引用除了傳遞地址外,還是perl中將標(biāo)量(scalar)、列表(list)、哈希(hash)進(jìn)行一般化(或者說統(tǒng)一)表示的機(jī)制,使用引用后,可以將標(biāo)量、列表、哈希均表示為標(biāo)量(因?yàn)榈刂繁举|(zhì)上是一個(gè)無符號(hào)整型數(shù),這一點(diǎn)與C中的void*有些類似)。通過引用,就可以解決perl中無法存儲(chǔ)帶有嵌套層次的列表、無法表示復(fù)雜數(shù)據(jù)結(jié)構(gòu)的問題。
Perl引用分為直接引用和符號(hào)引用,每種Perl引用都有各自的特點(diǎn)和作用,這里向大家簡單介紹一下Perl直接應(yīng)用的概念,希望對(duì)大家學(xué)習(xí)有所幫助。
Perl直接引用
1、一般的標(biāo)量Perl引用
如:
sub add{ my($a,$b)=@_; $$a++; $$b++; }
$a=1; $b=2;
add(\$a,\$b); print "$a,$b\n"; 輸出:2,3。 說明:取變量的Perl引用可以用“\”符號(hào)。解Perl引用用“$”符號(hào)。
2、數(shù)組的Perl引用
數(shù)組的Perl引用和標(biāo)量的Perl引用一樣,在數(shù)組名前面加“\”,只是在解Perl引用的時(shí)候,使用@符號(hào)。如: @abc=(1,2,3); $ref=\@abc; print “@$ref\n”;輸出1,2,3。 print “@$ref[0]\n”;輸出1。 對(duì)數(shù)組的Perl引用主要用在解決向函數(shù)傳遞若干個(gè)數(shù)組的問題。在Perl中,如果向函數(shù)傳遞若干個(gè)數(shù)組,則他們會(huì)將這些數(shù)組展開到@_數(shù)組中,并不能通過@_這個(gè)數(shù)組來區(qū)分傳遞過來的參數(shù)。 如:
sub add{ my(@ref1,@ref2)=@_; print(“ref1:@ref1\n”); print(“ref2:@ref2\n”); } @a=(1,2,3); @b=(1,2,3); @ret=add(@a,@b); 實(shí)際輸出的是:ref1:123123 ref2: 可以看到,在子函數(shù)add中,并沒有區(qū)分傳遞過來的兩個(gè)參數(shù)。那么如何向函數(shù)傳遞多個(gè)數(shù)組或哈希表呢? 解決的辦法是使用數(shù)組Perl引用。如下這個(gè)例子說明了如何實(shí)現(xiàn):
sub add{ my @result;
my($ref1,$ref2)=@_;
while( @$ref1 && @$ref2 ){
unshift @result, pop(@{$ref1})+pop(@{$ref2}); }
return @result; }
@a=(1,2,3);
@b=(1,2,3);
@ret=add(\@a,\@b);
print "@ret\n";
輸出:246
3、對(duì)哈希表的Perl引用
和數(shù)組類似,但是當(dāng)解Perl引用時(shí)要使用$符號(hào),如: %hash=(abc=>123, def=>456); $ref=\%hash; print "%$ref\n";輸出:%HASH(0x83179b4) print "$$ref{abc}\n";輸出:123
4、表的Perl引用
創(chuàng)建表的Perl引用將會(huì)把表中的最后一個(gè)值作為產(chǎn)生的標(biāo)量: $reflist=\($a,$b,$c); print $$reflist."\n"; #輸出$c的值。 $reflist=\(1,2...30,40); print $$reflist."\n"#輸出40
5、創(chuàng)建匿名數(shù)組的Perl引用
$arrayreference=[1,2,3]; print $$arrayreference[0]; #輸出1
print $arrayreference->[0]; #輸出1可以用箭頭解Perl引用
當(dāng)用pop從數(shù)組中取值時(shí),數(shù)組的第一個(gè)元素會(huì)被彈出,但是如果用pop用于匿名數(shù)組時(shí),可以實(shí)現(xiàn)取值而不影響原有數(shù)組,如: @a=(1,2,3); $s=pop@{[@a]};#perl作為快來計(jì)算@{},而快在計(jì)算時(shí)將創(chuàng)建對(duì)匿名數(shù)組的Perl引用。 print “@a\n”;#輸出123
當(dāng)反Perl引用數(shù)組Perl引用時(shí),該結(jié)果將插入到字符串中,如:想實(shí)現(xiàn)輸出uc函數(shù)的返回結(jié)果: print "uc(abc)\n"; #輸出uc(abc),并不能將abc轉(zhuǎn)換成大寫 print "@{[uc(abc)]}\n" #輸出ABC,通過數(shù)組Perl引用實(shí)現(xiàn)大寫轉(zhuǎn)換。 可以通過$#$的方式取匿名數(shù)組的長度: $a=[1,2,3,4]; print "$#$a\n";#輸出3,(最后一個(gè)元素的下標(biāo))
6、創(chuàng)建匿名哈希表的Perl引用
如: $hashreference={Name=>Sylvster,Gender=>male}; print $hashreference->{"Name"}; #輸出Sylvester,等價(jià)于:$$hashreference{Name}; 如果需要用each遍歷哈希表,則: while(($key,$value)=each(%$hashreference)){}
7、用匿名哈希表模仿用戶自定義數(shù)據(jù)類型
sub Point{ ($x,$y)=@_; return{ x=>$x, y=>$y }; } 當(dāng)使用Point類型時(shí),可以這樣做: $point=Point(10,20); print "x:$point->{x},y:$point->{y}\n";
#=========================
創(chuàng)建引用(reference):
solution 1:
$scalarref = \$foo; $arrayref = \@ARGV; $hashref = \%ENV; $coderef = \&handler; $globref = \*foo;
solution 2:
$scalarref = *foo{SCALAR}; $arrayref = *ARGV{ARRAY}; $hashref = *ENV{HASH}; $coderef = *handler{CODE}; $ioref = *STDIN{IO}; $globref = *foo{GLOB}; $formatref = *foo{FORMAT}; $globname = *foo{NAME}; # "foo" $pkgname = *foo{PACKAGE}; # "main"
REF:
http://perldoc./perlref.html#Making-References
http://www.cnblogs.com/mdyang/archive/2012/05/05/beginning-perl-4-chap-11-13.html
|