zoukankan      html  css  js  c++  java
  • 第八章 引用:

    第八章  引用:
    
    在C里,间接的最常见的形式就是指针,它可以让一个变量保存另外一个变量的内存地址。
    
    
    在Perl里,间接的最常见的形式是引用
    
    
    @vitals = ('john', 'mary', 'bill');
    
    一个引用可以指向任何数据结构。因为引用是标量,所以你可以把它们保存在数组的散列里,
    
    
    因此我们就可以做出数组的数组,散列的数组,数组的散列
    
    
    8.2.1  反斜杠操作符:
    
    
    你可以用一个反斜杠创建一个指向任何命名变量或者子过程的引用。(你还可以把它用于一个匿名标量值,
    
    比如7或"camel",尽管你通常并不需要这些东西。)  乍一看,这个操作符的作用类似C里的&(取址)操作符
    
    
    8.2.2.1  匿名数组组合器:
    
    你可以用方括弧创建一个指向匿名数组的引用:
    
    zjzc01:/root/big2# cat a6.pl 
    $arrayref = [1, 2, ['a', 'b', 'c', 'd']];
    
    print $arrayref."
    ";
    print @$arrayref."
    "; 
    print $$arrayref[0]."
    ";
    print $$arrayref[1]."
    ";
    print $$arrayref[2]."
    ";
    print $$arrayref[2][0]."
    ";
    print $$arrayref[2]->[0]."
    ";
    zjzc01:/root/big2# perl a6.pl 
    ARRAY(0x20e5608)
    3
    1
    2
    ARRAY(0x20c8d48)
    a
    a
    
    现在我们有一个方法来表示我们本章开头的表:
    
    
    
    zjzc01:/root/big2# cat a7.pl 
    $table = [ [ "john", 47, "brown", 186], [ "mary", 23, "hazel", 128], [ "bill", 35, "blue", 157] ];
    print "$table is $table
    ";
    print "@$table is @$table
    ";
    print $$table[0][0]."
    ";
    print $$table[0][1]."
    ";
    print $$table[1][0]."
    ";
    
    zjzc01:/root/big2# perl a7.pl 
    $table is ARRAY(0x1bf56d8)
    @$table is ARRAY(0x1bcdd48) ARRAY(0x1bea4a0) ARRAY(0x1bf5648)
    john
    47
    mary
    
    8.2.2.2   匿名散列组合器:
    
    
    你可以用花括弧创建一个指向匿名散列的引用:
    
    
    zjzc01:/root/big2# cat a8.pl 
    $hashref = {
    'Adam' => 'Eve',
    'Clyde' => $bonnie,
    'Antony' => 'Cleo' . 'patra',
    };
    print %$hashref."
    ";
    print $$hashref{Adam}."
    ";
    zjzc01:/root/big2# perl a8.pl 
    2/8
    Eve
    
    
    现在我们有了表示本章开头的另外一种方法:
    
    
    zjzc01:/root/big2# cat a9.pl 
    $table = {
    "john" => [47, "brown", 186],
    "mary" => [23, "hazel", 128],
    "bill" => [35, "blue", 157],
    };
    print $table."
    ";
    print %$table;
    print "
    ";
    print $$table{john}[0];
    print "
    ";
    zjzc01:/root/big2# perl a9.pl 
    HASH(0xb975f0)
    johnARRAY(0xb7ad48)billARRAY(0xb97578)maryARRAY(0xb97500)
    47
    
    这是一个数组散列,选择最好的数据结构是难度很高的工种,下一章专门讲这个。
    
    
    但是为了恶作剧,我们甚至可以将散列的散列用于我们的表:
    
    
    zjzc01:/root/big2# cat a10.pl 
    $table = {
    "john" => { age => 47,
    eyes => "brown",
    weight => 186,
    },
    "mary" => { age => 23,
    eyes => "hazel",
    weight => 128,
    },
    "bill" => { age => 35,
    eyes => "blue",
    weight => 157,
    },
    };
    print $table;
    print "
    ";
    print %$table;
    print "
    ";
    print $$table{john}{age};
    print "
    ";
    zjzc01:/root/big2# perl a10.pl 
    HASH(0x164c368)
    johnHASH(0x1628d48)billHASH(0x1645638)maryHASH(0x16455c0)
    47
    
    
    8.2.2.3  匿名子过程组合器:
    
    你可以通过不带子过程名字的sub创建一个匿名子过程:
    
    
    你可以通过用不带子过程名字的sub 创建一个匿名子过程:
    
    zjzc01:/root/big2# cat a11.pl 
    $coderef = sub {print "Boink!
    "};
    print &$coderef."
    ";
    
    zjzc01:/root/big2# perl a11.pl 
    Boink!
    1
    
    8.2.3   
    
    构造器可以用下列任何方法调用:
    $objref = Doggie::->new(Tail => 'short', Ears => 'long'); #1
    
    $objref = new Doggie:: Tail => 'short', Ears => 'long'; #2
    
    $objref = Doggie->new(Tail => 'short', Ears => 'long'); #3
    
    $objref = new Doggie Tail => 'short', Ears => 'long'; #4
    
    
    第一个和第2个调用方法是一样的,它们都调用了Doggie模块提供的一个叫new的函数。
    
    
    8.2.5  符号表引用:
    
    $scalarref = *foo{SCALAR}; # 和 $foo 一样
    
    $arrayref = *ARGV{ARRAY}; # 和 @ARGV 一样
    
    $hashref = *ENV{HASH}; # 和 \%ENV 一样
    
    $coderef = *handler{CODE}; # 和 &handler 一样
    
    $globref = *foo{GLOB}; # 和 *foo 一样
    
    $ioref = *STDIN{IO}; # ?...
    
    
    8.3.1  把一个变量当作变量名使用:
    
    
    
    bless 以一个普通的指向数据结构的引用参数。它将会把那个数据结构(注意,不是引用本身)
    
    标记为属于某个特定的包,于是这样就赋予了它更强大的功能。
    
    
    bless有两个参数:对象的引用、类的名称。 
    
    类的名称是一个字符串,代表了类的类型信息,这是理解bless的关键。 
    
    所谓bless就是把 类型信息 赋予 实例变量。
    
    
    一个象 $$arrayref[0] 这样的表达式等于
    
    ${$arrayref}[0] 并且意思是数组的第一个元素由 $arrayref 指向。
    
    8.3.2  把一个BLOCK块当作变量名用:
    
    
    8.3.3  使用箭头操作符:
    
    
    对于指向数组,散列,或者子过程的引用,第三种解引用的方法涉及到使用-> 中缀操作符。
    
    
    这样做就形成了一种语法糖,这样就让我们可以更容易访问独立的数组或者散列元素,或者间接地调用一个子过程。
    
    zjzc01:/root/big2# cat a12.pl 
    $arrayref=[a,b,c,d];
    print @$arrayref;
    print "
    ";
    print $$arrayref[2]."
    ";
    print ${ $arrayref }[2]."
    ";
    print $arrayref->[2]."
    ";
    
    zjzc01:/root/big2# perl a12.pl 
    abcd
    c
    c
    c
    
    
    zjzc01:/root/big2# cat a13.pl 
    $hashref={"a"=>1,"b"=>2,"c"=>3};
    print %$hashref;
    print "
    ";
    print $$hashref{a}."
    ";
    print ${ $hashref }{a}."
    ";
    print $hashref->{a}."
    ";
    zjzc01:/root/big2# perl a13.pl 
    c3a1b2
    1
    1
    1
    
    
    zjzc01:/root/big2# cat a14.pl 
    $array=[1,2,3,{"English"=>[a,b,c]}];
    
    print @$array;
    print "
    ";
    print $$array[3]->{"English"}->[0];
    print "
    ";
    zjzc01:/root/big2# perl a14.pl 
    123HASH(0xd6b488)
    a
    
    
    请注意 $array[3] 和 $array->[3] 是不一样的。第一个东西讲的是 @array 里的第四
    个元素,而第二个东西讲的是一个保存在 $array 里的数组(可能是匿名的数组)引用的
    第四个元素。
    
    8.3.4   使用对象方法:
    
    
    8.3.5   伪散列:
    
    zjzc01:/root/big2# cat a15.pl 
    $john = [ {age => 1, eyes => 2, weight => 3}, 47, "brown", 186 ];
    print @$john;
    print "
    ";
    print $$john[0]{age}."
    ";
    zjzc01:/root/big2# perl a15.pl 
    HASH(0x11c6d48)47brown186
    1
    
    8.3.6  硬引用可以用的其他技巧:
    
    8.3.7  闭包(闭包)
    
    
    我们早些时候谈到过用一个没有名字的sub{} 创建匿名子过程。
    
    
    你可以把那些子过程看作是在运行时定义,这就意味着它们有一个生成的时间和一个定义的地点。
    
    
    zjzc01:/root/big2# cat a16.pl 
    {
    my $critter = "camel";
    $critterref = $critter;
    };
    print "$critter is $critter
    ";
    print "$critterref is $$critterref
    ";
    
    zjzc01:/root/big2# perl a16.pl 
    $critter is 
    $critterref is camel
    
    $$critterref 的数值仍将是“camel”,即使在离开闭合的花括弧之后 $critter 消失了也如
    此。但是 $critterref 也可以指向一个指向了 $critter 的子过程:
    
    (请注意这些与闭合相关的事情只适用于 my 变量。全局量还是和往
    常一样运转,因为它们不是按照词法变量的方式创建和删除的。)
    
    

  • 相关阅读:
    推荐Windows下SVN服务器端和客户端工具软件
    QT的一些小知识
    Qt
    Qt
    ADB
    HTTP
    Python
    项目附
    项目
    架构
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13351118.html
Copyright © 2011-2022 走看看