【问题标题】:Building a variable depth hash reference data structure in perl在 perl 中构建可变深度哈希引用数据结构
【发布时间】:2010-07-21 17:50:22
【问题描述】:

我需要在 perl 中构建一个可变深度的哈希数据结构。最终我找到了这段代码:


#!/usr/bin/perl -w
use strict;

my %hash;
my $value = "foo";
my @cats = qw(a b c d);

my $p = \%hash;
foreach my $item (@cats) {
 $p->{$item} = {} unless exists($p->{$item});
 $p = $p->{$item};
}

我的问题是它如何以及为什么起作用。我以为我知道 perl 是如何工作的。在这段代码中,我没有看到 \%hash 值被重置,并且似乎 $p (这是一个局部变量)在每个循环中都被重置。我什至可以通过数据转储器看到它: 运行:


#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;

my %hash;
my $value = "foo";
my @cats = qw(a b c d);

my $p = \%hash;
foreach my $item (@cats) {
 print "BEFORE:\n";
 print Dumper(\%hash);
 #print Dumper($p);
 $p->{$item} = {} unless exists($p->{$item});
 $p = $p->{$item};
 print "AFTER:\n";
 print Dumper(\%hash);
 #print Dumper($p);
}

然后用

取消注释该行
#print Dumper($p)
清楚地表明 $p 每次都是一个新变量。

如果 $p 每次都重置,\%hash 是如何构建的?

【问题讨论】:

    标签: perl


    【解决方案1】:

    $p 不是每次都被“重置”;它被设置为哈希中的下一个较低级别,即刚刚添加的级别。此时它只是一个空的 hashref,{},因为它将在下一次循环迭代中填充。

    我不确定您如何得出结论,$p 每次都是一个新变量,但这是不正确的。它只是指向%hash 结构中的一个新位置。由于它是在循环之外声明的,因此它不会随着循环的迭代而丢失其值。

    【讨论】:

      【解决方案2】:

      向$p 所指的哈希添加一个显式标记:

       ...
       print "AFTER:\n";
       $p->{'$p'} = 'is here!';
       print Dumper(\%hash);
       delete $p->{'$p'};
      }
      

      那么最后几个 AFTER 转储看起来像

      之后:
      $VAR1 = {
        '一个' => {
          'b' => {
            'c' => {
              '$p' => '来了!'
            }
          }
        }
      };
      
      后:
      $VAR1 = {
        '一个' => {
          'b' => {
            'c' => {
              'd' => {
                '$p' => '来了!'
              }
            }
          }
        }
      };

      是的,在每个新的深度,$p 指的是一个空哈希,但退后一步查看%hash 的整体结构。

      【讨论】:

        【解决方案3】:

        想看一些很酷的东西吗?这做同样的事情(只是你永远不会看到它分配了 hashref!)

        my $p = \\%hash; # $p is a reference to a hashref
        foreach my $item (@cats) {
            # because $p references a reference, you have to dereference
            # it to point to the hash.
            $p = \$$p->{$item} unless exists $$p->{$item};
        }
        

        当你引用它时,槽位是autovivified,当它像哈希引用一样被寻址时,它会创建那个哈希引用。

        【讨论】:

          猜你喜欢
          • 2013-04-16
          • 2015-03-26
          • 1970-01-01
          • 1970-01-01
          • 2014-05-06
          • 2012-10-26
          • 2013-07-31
          • 1970-01-01
          • 2011-01-26
          相关资源
          最近更新 更多