Perl:在这种情况下我可以跳过中间哈希变量吗?

问题描述 投票:0回答:1

目前,我使用这样的东西:

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
”。

有什么想法可以做到吗?

perl hash subroutine
1个回答
9
投票

从返回的列表中创建一个哈希引用,然后您可以取消引用

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

在您尝试的内容中,

${ ... }
在内部强加了标量上下文。 来自 perlref(我的重点)

2. 无论您将标识符(或标识符链)作为变量或子例程名称的一部分,您都可以用 BLOCK 返回正确类型的引用替换该标识符。

在标量上下文中,哈希值被评估为带有分数涉及存储桶的字符串;不是哈希引用。


更新 我认为将哈希作为平面列表返回是有设计原因的。如果情况并非如此,那么明确的解决方案是仅从 sub 返回一个 hashref。

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

至于性能优势......如果您可以看到差异,则说明您要么有大量的哈希值,无论如何都应该通过引用处理,要么有太多的函数调用可能需要重构。

要通过参考返回,您可以

  • 在子中形成并使用哈希,然后

    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 中直接更改调用者的数据并不常见。如果您只需要在子中填充哈希,然后在那里构建它并

    return \%hash;

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