zoukankan      html  css  js  c++  java
  • perl中的引用

    为什么使用引用?

    在perl4中,hash表中的value字段只能是scalar,而不能是list,这对于有些情况是很不方便的,比如有下面的数据:

    Chicago, USA Frankfurt, Germany Berlin, Germany Washington, USA Helsinki, Finland New York, USA

    我们想要按国家将城市分类,每个国家后面对应城市列表,如果用perl4来做,必须将城市列表组合成字符串才行,如果用perl5就可以用引用来做,有了引用,就可以构造复杂的hash结构,就可以用列表作为hash的值了。

    如何定义引用

    方法一 使用斜线\

    定义变量的时候,在变量名前面加个\,就得到了这个变量的一个引用,比如

     
    # 数组的引用my@array= (1,2,3) ; my$aref=\@array ;
    #哈希的引用my%hash= ("name"=>"zdd","age"=>30,"gender"=>"male") ; my$href=\%hash ;
    #标量的引用my$scalar=1 ; my$sref=\$scalar ;
     

    方法二 匿名引用

    方法一不是很常用,最常用的还是匿名引用,方法如下

    匿名数组引用-用[]定义

    $aref= [ 1,"foo",undef,13 ];

    匿名数组的元素仍然可以是匿名数组,所以我们可以用这种方法构造数组的数组,可以构造任意维度的数组。

    my $aref = [         [1, 2, 3],         [4, 5, 6],         [7, 8, 9], ]

    匿名哈希引用-用{}定义

    $href= { APR =>4, AUG =>8 };

    使用引用

    定义了引用之后,可以使用不同的方法来访问引用,这里主要有三种方法。记忆这三种方法有个诀窍,将他们与普通的变量访问作比较即可。

    方法一

    与普通变量的访问方法相比,假设原来的变量名是name,则此方法在所有name出现的地方用$name代替,如下

     
    my $scalar = 1 ; 
    my @array = (1, 2, 3) ;
    my %hash = ('zdd' => 30, 'autumn' => 27) ;

    my $sref = \$scalar ; # scalar reference
    my $aref = \@array ; # array referencem
    y
    $href = \%hash ; # hash reference
    # 方法一
    print $$sref, "\n" ;  # 用$sref代替sref
    print @$aref, "\n" ; # 用$aref代替aref
    print %$href, "\n" ; # 用$href代替href
    print $$aref[2], "\n" ;
    print $$href{'zdd'}, "\n" ;
     

    方法二

    与普通变量的访问方法相比,假设变量原来的名字是name,则现在用{$name}来代替name。

    @a        @{$aref}         
    An array
    reverse@a  reverse @{$aref}    Reverse the array
    $a[3]      ${$aref}[3]       An element of the array
    $a[3] =17; ${$aref}[3] =17    Assigning an element

    同理,哈希引用的使用方法如下。

    %h          %{$href}           A hash    
    keys%h      keys%{$href}       Get the keys from the hash
    $h{'red'}     ${$href}{'red'}      An element of the hash
    $h{'red'} =17   ${$href}{'red'} =17   Assigning an element

    注意:当{}内部是$var的形式时,{}是可以省略的,也就是说@{$aref}等价于@$aref,不过初学最好养成使用{}的习惯。

    方法三

    前两种方法比较繁琐,这种很简洁,就是使用箭头符号->

    $aref->[]  数组解引用

    $href->{}  哈希解引用

    $href->()  子过程解引用

    $aref->[0] =3 ;  $href->{name} ="autumn" ;  $sref=2 ;

    也可以将引用赋值给其他变量

    my$aref1=$aref ; my$href1=$href ; my$scalar1=$scalar ;

    解引用总结

     
    my $scalar = 1 ; 
    my @array = (1, 2, 3) ;
    my %hash = ('zdd' => 30, 'autumn' => 27) ;
    my $sref = \$scalar ; # scalar reference
    my $aref = \@array ; # array referencem
    y
    $href = \%hash ; # hash reference #
    方法一

    print $$sref, "\n" ;
    print @$aref, "\n" ;
    print %$href, "\n" ;
    print $$aref[2], "\n" ;
    print $$href{'zdd'}, "\n" ;
    # 方法二
    print ${$sref}, "\n" ;
    print @{$aref}, "\n" ;
    print %{$href}, "\n" ;
    print ${$aref}[2], "\n" ;
    print ${$href}{'zdd'}, "\n" ;
    # 方法三,不适用于标量
    print $aref->[0], "\n" ;
    print $href->{'zdd'}, "\n" ;
     

    数组的数组

    @a = (     [1, 2, 3],     [4, 5, 6],     [7, 8, 9] )

    我们知道[1, 2, 3]定义了一个(1, 2, 3)的匿名引用,所以数组a实际上包含三个元素,每个元素是一个引用,该引用指向一个数组,所以我们可以用下面的方法来访问数组元素(注意,下标从0开始)

    $a[1][2]表示第二行第三列元素6,也可以写成$a[1]->[2],不过很少有人这么写。还可以写成${$a[1]}[2],几乎没人这么写!

    多维数组的另一个写法如下:

    my $aref = [1, [2, 3], [4, 5, 6]] ; 
    print $aref->[0] , "\n" ; #1
    print $aref->[1][1], "\n" ; #3
    print $aref->[2][0], "\n" ; #4

    这两者的区别有以下几点:

    • 前者是真正的数组,所以定义变量是使用@,后者是指向匿名数组的引用,所以定义的时候使用$
    • 前者的数组元素是匿名数组,而外层数组则是实体数组,后者无论元素还是外层数组都是匿名数组
    • 前者可以用$a[x][y]的形式访问,而后者只能用解引用的方式访问,即$a->[x][y]的形式。

    数组的哈希

    哈希的数组

    哈希的哈希

    也就是哈希表中的每个元素也是一个哈希表,比如一个学生集合组成的哈希,其key是学生名字(唯一),其值是每个学生的属性,比如年龄,身高及学号等。

     
    my $student_properties_of = {    
    'zdd' => { 'age' => 30, 'hight' => 170, 'id' => '001', },
    'autumn' => { 'age' => 27, 'hight' => 165, 'id' => '002', }
                     } ;
     

    引用的赋值

    $aref2 = $aref1; 将使得$aref2和$aref1指向同一个数组,如果想将$aref1指向的数组拷贝一份给$aref2的话,使用下面的方法,[]里面对数组进行解引用,而[]以解引用后的数组为内容生成了一个新的匿名数组,又赋值给$aref2。

    $aref2 = [@{$aref1}]; 

    注意:不能使用下面的形式,外层的[]是不可缺少的。由于=左边是标量,所以右边的数组会被解释为标量环境,得到的是数组元素个数,而不是元素本身。但是如果加上[]就可以了,这样perl知道这是一个匿名数组的赋值。

    $aref2 = @{$aref1};

    判断一个变量是否是引用

    使用ref函数即可,如果变量是引用则返回真,否则返回假。实际上它更智能,它会返回引用对应的类型,比如HASH或者ARRAY。

    my $aref1 = [1, 2, 0] ;
    print ref $aref1, "\n" ; #输出 ARRAY
    if (ref $aref1)
    { print "true\n" ; #输出 true }

    判断两个引用是否指向同一个目标

    可以用eq,这将以字符串的形式判断,也可以使用==

    my $aref1 = [1, 2, 0] ;
    my $aref2 = $aref1 ;
    print $aref1, "\n" ;
    print $aref2, "\n" ;
    if ($aref1 eq $aref2)
      { print "reference equal\n" ; }
    if($aref1 == $aref2)
      { print "reference equal\n" ; }
     

    产生如下输出

    ARRAY(0x248bec) ARRAY(0x248bec) reference equal (eq) reference equal (==)

  • 相关阅读:
    Building a flexiable renderer
    Indirect Illumination in mental ray
    我的心情
    Cellular Automata
    Subsurface Scattering in mental ray
    Shader Types in mental ray
    BSP Traversal
    我的渲染器终于达到了MR的速度
    How to handle displacement and motion blur
    说明
  • 原文地址:https://www.cnblogs.com/blueicely/p/2816110.html
Copyright © 2011-2022 走看看