zoukankan      html  css  js  c++  java
  • Perl引用reference(\运算符)

    引用

    引用一律声明为标量类型(即$开头的命名变量),使用\运算符取引用
    对引用变量的修改等同于对引用指向实际数据的修改
    标量变量引用: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

  • 相关阅读:
    计数排序【代码】
    快速排序【代码】
    基于最大堆实现最大优先队列
    Spring入门(1)
    AJAX初步理解
    选择器
    Hibernate的映射
    Hibernate配置(2)
    查看mysql的安装路径
    Hibernate入门(1)
  • 原文地址:https://www.cnblogs.com/emanlee/p/2645920.html
Copyright © 2011-2022 走看看