【问题标题】:Perl's hash of hash of hash redeclaration?Perl 的 hash of hash 的 hash 重声明?
【发布时间】:2015-04-10 09:26:16
【问题描述】:

假设我有一个带有一些值的 Hash of Hash (%hash)

warn Dumper \%hash;
     'Key1'=> {'Subkey1'} => {'SubSubkey11'} => {'Value1'} 
     'Key2'=> {'Subkey2'} => {'SubSubkey22'} => {'Value2'}
     ...

然后,想要验证某个键组合是否不存在(假设 if 上方有一个 for 循环遍历 $val1 和 $val2 的一系列组合)。

if (!exists $hash{$val1}{$val2} ) {  #### I am only verifying the existent of the Key and Subkey, not SubSubkey
     print "Doesn't exists";
}

如果我在循环结束后使用,我会看到如下内容:

warn Dumper\%hash; 
     'Key1' => {'Subkey1'} => {}
     'Key2' => {'Subkey2'} => {}

'Key1' 和 'Subkey1' 以某种方式被“分配”给 void 值,因为我可能会在不存在的键的相同组合上循环多次,在第一次循环遍历一对键之后,第二个 if 需要组合存在。

造成这种情况的原因以及解决它的最佳方法是什么。我尝试在 if 中取消引用哈希并收到此错误

    exists argument is not a HASH or ARRAY element or a subroutine 

【问题讨论】:

    标签: perl hash


    【解决方案1】:

    发生这种情况是因为您将$hash{$var1} 视为哈希引用,因此它会自动变为一个;这称为自动激活,非常方便。

    您可以通过安装和使用 autovivification pragma 来禁用它:

    if ( do { no autovivification; ! exists $hash{$var1}{$var2} } ) {
    

    或者您可以手动执行与此操作基本相同的操作:

    if ( ! exists ${ $hash{$var1} || {} }{$var2} ) {
    

    (这里,如果 $hash{$var1} 没有设置,我们不将其用作哈希引用,而是使用空哈希。)

    或者,如果它对您来说更具可读性,您可以这样做:

    if ( ! ( $hash{$var1} && exists $hash{$var1}{$var2} ) ) {
    

    【讨论】:

    • 如果散列元素永远不存在,但有一个 false 值(正如你用$hash{$var1} || {} 假设的那样),那么你可以只写unless ( $hash{$var1} and $hash{$var1}{$var2} ) { ... }
    • 以重复 $hash{$var1 为代价,这可能是复杂的表达式。但是,是的,在简单的情况下,这会更容易阅读
    猜你喜欢
    • 1970-01-01
    • 2012-04-19
    • 1970-01-01
    • 2013-12-03
    • 1970-01-01
    • 2020-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多