设为首页 收藏本站
查看: 1714|回复: 0

[经验分享] Perl引用reference(\运算符)

[复制链接]

尚未签到

发表于 2015-12-25 14:21:50 | 显示全部楼层 |阅读模式
  引用
  引用一律声明为标量类型(即$开头的命名变量),使用\运算符取引用
对引用变量的修改等同于对引用指向实际数据的修改      
标量变量引用: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);
  因为\@array1本质上只是一个标量,所以列表不会被扁平化,依旧保留了嵌套层次      
对匿名列表的引用:将列表的()替换为[]:my $array_r = [1, 2, 3, 4, 5];      
对匿名哈希的引用:将哈希的()替换为{}:my $hash_r = { apple => "pomme", pear => "poire" };      
对引用变量解引用通过{$var_r}实现      
列表      
     my @array = (1, 2, 3, 4, 5);      
     my $array_r = \@array;      
     my @array2 = @{$array_r};  #拷贝了数组
  哈希与列表类似      
对于数组引用,可以将${$ref}简记为$ref->,例如可以将${$ref}[2]简记为$ref->[2],而将${${ref}[2]}[1]简记为$ref->[2]->[1],并进一步简记为$ref->[2][1]      
使用undef销毁一个引用:undef $ref; perl对于引用指向的数据维护一个引用计数,当计数减到0时引用指向的数据被销毁,内存空间被释放      
使用引用使得表示复杂的数据结构成为可能。这些数据结构包括矩阵(多维数组)、链表、树、图等。      
一些思考:C/C++的引用主要为了传地址。与C/C++中的指针、引用不同的是,perl引用除了传递地址外,还是perl中将标量(scalar)、列表(list)、哈希(hash)进行一般化(或者说统一)表示的机制,使用引用后,可以将标量、列表、哈希均表示为标量(因为地址本质上是一个无符号整型数,这一点与C中的void*有些类似)。通过引用,就可以解决perl中无法存储带有嵌套层次的列表、无法表示复杂数据结构的问题。
  
  Perl引用分为直接引用符号引用,每种Perl引用都有各自的特点和作用,这里向大家简单介绍一下Perl直接应用的概念,希望对大家学习有所帮助。
  Perl直接引用
  1、一般的标量Perl引用
     如:
  sub add{  my($a,$b)=@_;  $$a++;  $$b++;  }  
  $a=1;  $b=2;  
  add(\$a,\$b);  print "$a,$b\n";       输出:2,3。     
     说明:取变量的Perl引用可以用“\”符号。解Perl引用用“$”符号。
  2、数组的Perl引用
  数组的Perl引用和标量的Perl引用一样,在数组名前面加“\”,只是在解Perl引用的时候,使用@符号。如:      
     @abc=(1,2,3);      
     $ref=\@abc;      
     print “@$ref\n”;输出1,2,3。      
     print “@$ref[0]\n”;输出1。      
对数组的Perl引用主要用在解决向函数传递若干个数组的问题。在Perl中,如果向函数传递若干个数组,则他们会将这些数组展开到@_数组中,并不能通过@_这个数组来区分传递过来的参数。      
如:
  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);  
   实际输出的是:ref1:123123      
   ref2:      
可以看到,在子函数add中,并没有区分传递过来的两个参数。那么如何向函数传递多个数组或哈希表呢?      
解决的办法是使用数组Perl引用。如下这个例子说明了如何实现:
  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、对哈希表的Perl引用
  和数组类似,但是当解Perl引用时要使用$符号,如:      
    %hash=(abc=>123, def=>456);      
    $ref=\%hash;      
    print "%$ref\n";输出:%HASH(0x83179b4)      
    print "$$ref{abc}\n";输出:123
  4、表的Perl引用
  创建表的Perl引用将会把表中的最后一个值作为产生的标量:      
     $reflist=\($a,$b,$c);      
     print $$reflist."\n"; #输出$c的值。      
     $reflist=\(1,2...30,40);      
     print $$reflist."\n"#输出40
  5、创建匿名数组的Perl引用
  $arrayreference=[1,2,3];  print $$arrayreference[0]; #输出1  
  print $arrayreference->[0]; #输出1可以用箭头解Perl引用   
  当用pop从数组中取值时,数组的第一个元素会被弹出,但是如果用pop用于匿名数组时,可以实现取值而不影响原有数组,如:     
     @a=(1,2,3);      
     $s=pop@{[@a]};#perl作为快来计算@{},而快在计算时将创建对匿名数组的Perl引用。      
     print “@a\n”;#输出123
  当反Perl引用数组Perl引用时,该结果将插入到字符串中,如:想实现输出uc函数的返回结果:     
     print "uc(abc)\n"; #输出uc(abc),并不能将abc转换成大写      
     print "@{[uc(abc)]}\n" #输出ABC,通过数组Perl引用实现大写转换。      
可以通过$#$的方式取匿名数组的长度:      
     $a=[1,2,3,4];      
     print "$#$a\n";#输出3,(最后一个元素的下标)
  6、创建匿名哈希表的Perl引用
  如:     
     $hashreference={Name=>Sylvster,Gender=>male};      
     print $hashreference->{"Name"}; #输出Sylvester,等价于:$$hashreference{Name};      
如果需要用each遍历哈希表,则:      
     while(($key,$value)=each(%$hashreference)){}
  7、用匿名哈希表模仿用户自定义数据类型
       sub Point{     
     ($x,$y)=@_;      
     return{      
     x=>$x,      
     y=>$y      
     };      
     }      
当使用Point类型时,可以这样做:      
     $point=Point(10,20);      
     print "x:$point->{x},y:$point->{y}\n";
  #=========================
  创建引用(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.perl.org/perlref.html#Making-References
  http://www.cnblogs.com/mdyang/archive/2012/05/05/beginning-perl-4-chap-11-13.html

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-156238-1-1.html 上篇帖子: perl 常用module的使用 下篇帖子: Perl爬虫--爬特定内容的网页
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表