【问题标题】:perl hash ref return: { 'a' =>1, % { sub() } } [closed]perl hash ref return: { 'a' =>1, % { sub() } } [关闭]
【发布时间】:2020-06-30 01:20:03
【问题描述】:
{ 'a' =>1, % { sub() } }

这是否最适合将作为 ref 返回的哈希包含到 other 中?

%$sub() 不起作用。

到目前为止,我 new {} 生成了新的哈希并返回引用,可能新优化了这种情况,但不确定。

【问题讨论】:

  • 问题缺乏清晰性。
  • 无法回答我的问题,至少不要弄乱我的线程 - 谢谢。
  • 无法提问? How to ask

标签: perl hash reference return


【解决方案1】:

是的,要取消引用哈希引用并获取键/值对列表,请将%{ ... } 包裹在生成哈希引用的表达式周围。

或者,从 perl 5.24 开始,您可以使用后缀解引用语法 sub()->%*

【讨论】:

  • 谢谢,后缀看起来并没有更短或更清晰。
  • 对于简单的结构,后缀不会发光。当你进入一长串的事情时,严格从左到右阅读真的很有帮助。
【解决方案2】:

我猜您有一些返回哈希引用的子例程,并且您希望将所有这些键包含在更大的哈希中:

my $hash_ref = some_sub(...);
my $big_hash = { a => 1 };

您可以通过多种方式进行操作。在您的问题中,您似乎正试图通过取消引用返回值来内联。这可能是合理的。环绕符号或postfix dereference 可以做到这一点:

# general circumfix (old way)
my $big_hash = { a => 1, %{ some_sub() } };

# postfix dereference (new v5.24 hotness)
my $big_hash = { a => 1, some_sub()->%* };

但是,我倾向于不喜欢直接这样做。通常我会在默认值可能被 some_sub() 覆盖时这样做:

my %defaults = ( ... );

my %big_hash = ( %defaults, some_sub()->%* );

但是,我通常会更进一步,将产生默认值的东西放入另一个子例程中,这样我就可以为子类提供一种覆盖它的方法:

sub defaults {
   my %defaults = ( ... );
   return \%defaults;
   }

my %big_hash = ( defaults()->%*, some_sub()->%* );

还有许多其他方法可以合并哈希。 StackOverflow 上有How can I combine hashes in Perl?,perlfaq4 中也有How do I merge two hashes

但是,还有另一件事需要考虑。简单地将两个哈希混合在一起以获得一个新的哈希可能会很昂贵。如果第一个哈希非常非常大怎么办?

my %grand_hash = ( %very_big_hash, %new_hash );

人们经常这样做并分配回起始哈希值,主要是因为它很容易输入:

my %grand_hash = ( %grand_hash, %new_hash );

您告诉 Perl 展开 %grand_hash,将另一个列表与其合并,然后重新散列庞大的列表。

虽然有点笨拙,但更好的方法是添加新的键和值。

foreach my $new_key ( keys %new_hash ) {
    $grand_hash{$new_key} = $new_hash{$new_key};
    }

当您需要做其他事情时,这很好,例如跳过哈希中已有的键:

foreach my $new_key ( keys %new_hash ) {
    next if exists $grand_hash{$new_key};
    $grand_hash{$new_key} = $new_hash{$new_key};
    }

或者可能添加到已经存在的值而不是替换它:

foreach my $new_key ( keys %new_hash ) {
    $grand_hash{$new_key} += $new_hash{$new_key};
    }

如果您只需要添加它而不关心替换值,那么哈希切片非常适合同时分配多个键和值:

@grand_hash{ keys %new_hash } = values %new_hash;

在您的情况下,您将调用一次子例程并存储结果,这样您就不必再次构造散列。然后,您取消引用该哈希是切片(或任何您想使用它的地方:

my $new_hash = some_sub(...);
@grand_hash{ keys %$new_hash } = values %$new_hash;

【讨论】:

  • 很酷,您提供了如此描述性的答案。就像Erwin 的答案。这样的答案很有帮助,我希望能为 perl 社区带来新的血液(更多的新手)
猜你喜欢
  • 2014-11-09
  • 1970-01-01
  • 1970-01-01
  • 2014-05-15
  • 2011-10-21
  • 1970-01-01
  • 2021-10-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多