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 reference
    my $href = %hash ; # hash reference

    # 方法一
    print $$sref, " " ;  # 用$sref代替sref
    print @$aref, " " ;   # 用$aref代替aref
    print %$href, " " ;   # 用$href代替href
    print $$aref[2], " " ;
    print $$href{'zdd'}, " " ;
    复制代码

    方法二

    与普通变量的访问方法相比,假设变量原来的名字是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 reference
    my $href = %hash ; # hash reference

    # 方法一
    print $$sref, " " ;
    print @$aref, " " ;
    print %$href, " " ;
    print $$aref[2], " " ;
    print $$href{'zdd'}, " " ;

    # 方法二
    print ${$sref}, " " ;
    print @{$aref}, " " ;
    print %{$href}, " " ;
    print ${$aref}[2], " " ;
    print ${$href}{'zdd'}, " " ;

    # 方法三,不适用于标量
    print $aref->[0], " " ;
    print $href->{'zdd'}, " " ;
    复制代码

    数组的数组

    @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] , " " ; #1
    print $aref->[1][1], " " ; #3
    print $aref->[2][0], " " ; #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, " " ; #输出 ARRAY

    if (ref $aref1) {
    print "true " ; #输出 true
    }
    复制代码

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

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

    复制代码
    my $aref1 = [1, 2, 0] ;
    my $aref2 = $aref1 ;
    print $aref1, " " ;
    print $aref2, " " ;

    if ($aref1 eq $aref2) {
    print "reference equal " ;
    }
    if($aref1 == $aref2) {
    print "reference equal " ;
    }
    复制代码

    产生如下输出

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

  • 相关阅读:
    Python--前端之HTML
    Python--MySql(主键的创建方式、存储引擎、存储过程、索引、pymsql)
    python--MySql(外键约束、多表查询(*****))
    python--MySql 表记录的操作
    python--MySql
    Python--线程队列(queue)、multiprocessing模块(进程对列Queue、管道(pipe)、进程池)、协程
    Python--同步锁(互斥锁)、死锁(状态)、递归锁、信号量、Event对象
    Python--多线程、多进程常用概念
    Python--基础之socket编程
    ubuntu 安装 flashplayer
  • 原文地址:https://www.cnblogs.com/ZeroTiny/p/4721067.html
Copyright © 2011-2022 走看看