{ 'a' =>1, % { sub() } }
最适合将作为参考返回的哈希值包含在其他变量中吗?
%$sub()
不起作用。到目前为止,我的新{}进行了新的哈希处理并返回了引用,这种情况下,新的可能优化了,但不确定。
%{ ... }
。或者,从perl 5.24开始,您可以使用后缀取消引用语法sub()->%*
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;
请参见以下代码段进行演示
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;
}
}