代码之家  ›  专栏  ›  技术社区  ›  Georg

Perl:在这种情况下,我可以跳过中间散列变量吗?

  •  4
  • Georg  · 技术社区  · 8 年前

    目前,我使用这样的方法:

    my %tmpHash = routineReturningHash();
    my $value = $tmpHash{'someKey'};
    

    我唯一需要的是 $value ,我不需要 %tmpHash 它本身所以我很想知道是否有办法避免 %tmpHash公司

    my $value = ${routineReturningHash()}{'someKey'};
    

    但它不工作,并输出一个奇怪的错误:“ Can't use string ("1/256") as a HASH ref while "strict refs" in use ".

    你知道怎么做吗?

    1 回复  |  直到 8 年前
        1
  •  9
  •   zdim    8 年前

    从返回的列表中创建一个hashref,然后可以对其进行解引用

    my $value = { routineReturningHash() }->{somekey};
    

    在你尝试的过程中 ${ ... } 在内部施加标量上下文。 From perlref (我的重点)

    2. 任何将标识符(或标识符链)作为变量或子例程名称的一部分的地方,都可以用块替换标识符 返回引用 类型正确。

    involving buckets ; 不是hashref。


    使现代化 我认为将哈希作为平面列表返回是有设计原因的。如果不是这样,那么明确的解决方案是只从sub返回一个hashref。

    这还保存了一个数据副本:当您返回散列时,需要复制标量(键和值),以向调用者提供一个列表;当返回引用时,只返回一个标量。

    要通过引用返回,您可以

    • 在sub中形成并使用哈希,然后 return \%hash;

    • 直接形成hashref return { key => 'value', ... };

    • 如果要处理一个大哈希,请传递其引用并使用它

      sub work_by_ref {    
          my ($hr) = @_;
          $hr->{key} = 'value';
          return 1;
      }
      
      my %hash;
      work_by_ref(\%hash);
      say "$_ => $hash{$_}" for sort keys %hash;
      

      小心这种C风格的方法;在Perl中,直接更改调用方的数据并不常见。如果只需要在sub中填充一个散列,那么在那里构建它并 返回\%散列;