哈希参考 - 重用内部哈希来存储和检索下一个值

Hash reference - Reuse inner hash to store and retrieve next values

我是 Perl 编程的新手,必须处理 Hash of Hashes。我正在尝试重用 innerHash 变量,使其本质上是动态的。我希望内部项目存储在 outerHash 中,我添加了多少。下面是我的测试程序片段。

use warnings;
sub testHash {  
  my %outerHash = ();

  my %innerHash1 = ();
  my %innerHash2 = ();

  $innerHash1{"key1"} = "value1";
  $innerHash1{"key2"} = "value2";
  $innerHash1{"key3"} = "value3";
  $outerHash{"Master1"} = \%innerHash1;

  $innerHash2{"key4"} = "value4";
  $innerHash2{"key5"} = "value5";
  $innerHash2{"key6"} = "value6";
  $outerHash{"Master2"} = \%innerHash2;

  #delete $innerHash1{$_};
  %innerHash1 = ();
  #undef %innerHash1;

  $innerHash1{"key7"} = "value7";
  $innerHash1{"key8"} = "value8";
  $innerHash1{"key9"} = "value9";
  $outerHash{"Master3"} = \%innerHash1;

  foreach $outerItem (keys %outerHash){
    print "\n$outerItem: ";
    foreach $innerItem (keys %{$outerHash{$outerItem}}){
        print "\t $innerItem = $outerHash{$outerItem}{$innerItem}";
    }
    print "\n-------------------------------------------------------";
  }
  print "\n";
}

testHash;

输出:

Master3:     key8 = value8   key7 = value7   key9 = value9
-----------------------------------------------------------------
Master2:     key5 = value5   key6 = value6   key4 = value4
-----------------------------------------------------------------
Master1:     key8 = value8   key7 = value7   key9 = value9
-----------------------------------------------------------------

我知道它在打印项目时使用了 innerHash1 的较新参考。在 outerHash 中拥有所有正确元素的正确方法是什么?在真实的编程场景中,我无法提前声明 n 个变量。

您可能是 perl 的新手,但您了解 指针 的概念,不是吗?代码 $outerHash{"Master1"} = \%innerHash1; 表示“$outerHash{"Master1"} 被分配了一个指向 %innerHash1 指针”。所以你观察到的是正确的和预期的。

如果您想继续重新创建 %innerHash 并将其添加到 %outerHash,您将需要做以下两件事之一:

  • 按值分配。 $outerHash{"Master1"} = {}; %{$outerHash{"Master1"}} = %innerHash1;
  • 每个循环只将 %innerHash 添加到 %outerHash 一次。由于 %innerHash 在循环内重新声明,而不是在循环外,它在每个循环中都超出范围,但由于 perl 的引用计数,它的内容将保留在 outerHash 中。根据您的观点,这可以考虑"trying to be too clever and potentially dangerous",但我认为还可以。

"right" 方法,至少在我看来,是根本不声明任何中介 "innerhashes"。直接使用引用即可:

my %outerHash;
$outerHash{Master1} = { key1 => 'value1', key2 => 'value2', key3 => 'value3'};
$outerHash{Master2} = { key4 => 'value4', key5 => 'value5', key6 => 'value6'};
$outerHash{Master3} = { key7 => 'value7', key8 => 'value8', key9 => 'value9'};

# or....
my %outerHash2;
$outerHash2{Master1}{key1} = 'value1';
$outerHash2{Master1}{key2} = 'value2';
$outerHash2{Master1}{key3} = 'value3';
$outerHash2{Master2}{key4} = 'value4';
$outerHash2{Master2}{key5} = 'value5';
$outerHash2{Master2}{key6} = 'value6';
$outerHash2{Master3}{key7} = 'value7';
$outerHash2{Master3}{key8} = 'value8';
$outerHash2{Master3}{key9} = 'value9';

# or...
my %outerHash3 = (
    Master1 => {
        key1 => 'value1',
        key2 => 'value2',
        key3 => 'value3'
    }
    Master2 => {
        key4 => 'value4',
        key5 => 'value5',
        key6 => 'value6'
    }
    Master3 => {
        key7 => 'value7',
        key8 => 'value8',
        key9 => 'value9'
    }
);