perl hash ref return:{'a'=> 1,%{sub()}}} [关闭]

问题描述 投票:1回答:2
{ 'a' =>1, % { sub() } }
最适合将作为参考返回的哈希值包含在其他变量中吗?

%$sub()不起作用。

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

perl hash reference return
2个回答
3
投票
是,要取消引用哈希引用并获取键/值对列表,请在生成哈希引用的表达式周围包裹%{ ... }

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


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

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;


-2
投票
问题缺乏问题的清晰度。

请参见以下代码段进行演示

use strict; use warnings; use feature 'say'; my $hash_ref = { 'a' => 1, 'b' => sub { say 'I am anon sub'; } }; while( my($k,$v) = each %{$hash_ref} ) { if( ref $v eq 'CODE' ) { say "$k => CODE"; $v->(); } else { say "$k => " . $v; } }

© www.soinside.com 2019 - 2024. All rights reserved.