Perl中的散列和散列引用有什么区别? [英] What's the difference between a hash and hash reference in Perl?

查看:171
本文介绍了Perl中的散列和散列引用有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想正确理解Perl中的哈希。我不得不间歇地使用Perl一段时间,大多数时候我需要这样做,它主要与文本处理有关。



每次,我都必须处理随着哈希,它会变得混乱。我发现哈希的语法非常模糊



散列和哈希引用的一个很好的解释,它们的区别,当它们被需要时等等,我们将非常感激。

解决方案

简单的哈希函数接近数组。他们的初始化甚至看起来相似。首先是数组:

  @last_name =(
Ward,Cleaver,
Fred ,Flintstone,
Archie,Bunker
);

现在让我们使用散列表示相同的信息(又名关联数组):

 %last_name =(
Ward,Cleaver,
Fred,Flintstone,
Archie,Bunker
);

尽管它们具有相同的名称,但数组 @last_name 和散列%last_name 是完全独立的。



有了数组,如果我们想知道Archie的姓氏,我们必须执行线性搜索:

  my $ lname; ($ my $ i = 0; $ i <@last_name; $ i + = 2){
$ lname = $ last_name [$ i + 1]
if $ last_name [$ i] eq阿尔奇;
}
打印Archie $ lname\\\
;

使用散列,它在语法上更直接:

 打印Archie $ last_name {Archie} \\\
;

假设我们只想用稍微丰富的结构表示信息:




  • 切割者(姓氏)


    • 病房(名)

    • 6月(配偶的名字)


    • 石碑


      • Fred

      • Wilma


    • Bunker


      • Archie

      • Edith




    在引用出现之前,平键值散列是我们可以做的最好的,但引用允许

      my% personal_info =(
    Cleaver,{
    FIRST,Ward,
    SPOUSE,June,
    },
    Flintstone, {
    FIRST,Fred,
    SPOUSE,Wilma,
    },
    Bunker,{
    FIRST,Archie ,
    SPOUSE,Edith,
    },
    );

    在内部,%personal_info 都是标量,但这些值是一种特殊的标量:使用 {} 创建的哈希引用。这些参考使我们能够模拟多维哈希。例如,我们可以通过

      $ personal_info {Flintstone}  - > {SPOUSE} 

    请注意,Perl允许我们在下标之间省略箭头,所以上面的内容相当于

      $ personal_info {Flintstone} {SPOUSE} 

    如果您想了解有关Fred的更多信息,那么您可以输入很多内容,因此您可以使用某种游标获取引用:

      $ fred = $ personal_info {Flintstone}; 
    printFred的妻子是$ fred-> {SPOUSE} \\\
    ;

    因为上面代码片段中的 $ fred 是一个hashref,箭头是必要的。如果你放弃它,但明智地启用使用strict 来帮助你捕捉这些类型的错误,编译器会抱怨:

     全局符号%fred需要显式包名称... 

    Perl引用与C和C ++中的指针类似,但它们不能为空。 C和C ++中的指针需要解引用,因此需要在Perl中引用。



    C和C ++函数参数具有按值传递的语义:它们只是副本,不要回到调用者。如果你想看到更改,你必须传递一个指针。您可以在Perl中使用引用来获得这种效果:

      sub add_barney {
    my($ personal_info)= @_;

    $ personal_info-> {Rubble} = {
    FIRST => Barney,
    SPOUSE => 贝蒂,
    };
    }

    add_barney \%personal_info;

    没有反斜线, add_barney 一个副本在子回来后立即抛出。



    还要注意使用胖逗号( => )以上。它会自动引用左侧的字符串,并使得哈希初始化的语法更少。


    I would like to properly understand hashes in Perl. I've had to use Perl intermittently for quite some time and mostly whenever I need to do it, it's mostly related to text processing.

    And everytime, I have to deal with hashes, it gets messed up. I find the syntax very cryptic for hashes

    A good explanation of hashes and hash references, their differences, when they are required etc. would be much appreciated.

    解决方案

    A simple hash is close to an array. Their initializations even look similar. First the array:

    @last_name = (
      "Ward",   "Cleaver",
      "Fred",   "Flintstone",
      "Archie", "Bunker"
    );
    

    Now let's represent the same information with a hash (aka associative array):

    %last_name = (
      "Ward",   "Cleaver",
      "Fred",   "Flintstone",
      "Archie", "Bunker"
    );
    

    Although they have the same name, the array @last_name and the hash %last_name are completely independent.

    With the array, if we want to know Archie's last name, we have to perform a linear search:

    my $lname;
    for (my $i = 0; $i < @last_name; $i += 2) {
      $lname = $last_name[$i+1] if $last_name[$i] eq "Archie";
    }
    print "Archie $lname\n";
    

    With the hash, it's much more direct syntactically:

    print "Archie $last_name{Archie}\n";
    

    Say we want to represent information with only slightly richer structure:

    • Cleaver (last name)
      • Ward (first name)
      • June (spouse's first name)
    • Flintstone
      • Fred
      • Wilma
    • Bunker
      • Archie
      • Edith

    Before references came along, flat key-value hashes were about the best we could do, but references allow

    my %personal_info = (
        "Cleaver", {
            "FIRST",  "Ward",
            "SPOUSE", "June",
        },
        "Flintstone", {
            "FIRST",  "Fred",
            "SPOUSE", "Wilma",
        },
        "Bunker", {
            "FIRST",  "Archie",
            "SPOUSE", "Edith",
        },
    );
    

    Internally, the keys and values of %personal_info are all scalars, but the values are a special kind of scalar: hash references, created with {}. The references allow us to simulate "multi-dimensional" hashes. For example, we can get to Wilma via

    $personal_info{Flintstone}->{SPOUSE}
    

    Note that Perl allows us to omit arrows between subscripts, so the above is equivalent to

    $personal_info{Flintstone}{SPOUSE}
    

    That's a lot of typing if you want to know more about Fred, so you might grab a reference as sort of a cursor:

    $fred = $personal_info{Flintstone};
    print "Fred's wife is $fred->{SPOUSE}\n";
    

    Because $fred in the snippet above is a hashref, the arrow is necessary. If you leave it out but wisely enabled use strict to help you catch these sorts of errors, the compiler will complain:

    Global symbol "%fred" requires explicit package name at ...
    

    Perl references are similar to pointers in C and C++, but they can never be null. Pointers in C and C++ require dereferencing and so do references in Perl.

    C and C++ function parameters have pass-by-value semantics: they're just copies, so modifications don't get back to the caller. If you want to see the changes, you have to pass a pointer. You can get this effect with references in Perl:

    sub add_barney {
        my($personal_info) = @_;
    
        $personal_info->{Rubble} = {
            FIRST  => "Barney",
            SPOUSE => "Betty",
        };
    }
    
    add_barney \%personal_info;
    

    Without the backslash, add_barney would have gotten a copy that's thrown away as soon as the sub returns.

    Note also the use of the "fat comma" (=>) above. It autoquotes the string on its left and makes hash initializations less syntactically noisy.

    这篇关于Perl中的散列和散列引用有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆