【问题标题】:What does `$hash{$key} |= {}` do in Perl?`$hash{$key} |= {}` 在 Perl 中有什么作用?
【发布时间】:2010-09-14 08:53:18
【问题描述】:

我正在与一些使用哈希引用的 Perl 搏斗。

最后发现我的问题出在这行:

$myhash{$key} |= {};

即“为 $myhash{$key} 分配一个对空哈希的引用,除非它已经有值”。

但是,取消引用并尝试将其用作哈希引用会导致解释器在将字符串用作哈希引用时出错。

改成:

if( ! exists $myhash{$key}) {
  $myhash{$key} = {};
}

...让事情顺利进行。

所以我没有问题。但我很好奇发生了什么事。

谁能解释一下?

【问题讨论】:

    标签: perl initialization hash-reference


    【解决方案1】:

    您看到有关使用字符串作为哈希引用的错误的原因是您使用了错误的运算符。 |= 表示“按位或赋值”。换句话说,

      $foo |= $bar;
    

    相同
      $foo = $foo | $bar
    

    在您的示例中发生的情况是您的新匿名哈希引用被字符串化,然后与 $myhash{$key} 的值进行位或运算。更令人困惑的是,如果 $myhash{$key} 当时未定义,则该值是哈希引用的简单字符串化,看起来像 HASH(0x80fc284)。因此,如果您对结构进行粗略检查,它可能看起来 像一个哈希引用,但事实并非如此。以下是Data::Dumper 的一些有用输出:

       perl -MData::Dumper -le '$hash{foo} |= { }; print Dumper \%hash'
       $VAR1 = {
                 'foo' => 'HASH(0x80fc284)'
               };
    

    当您使用正确的运算符时,您会得到以下结果:

      perl -MData::Dumper -le '$hash{foo} ||= { }; print Dumper \%hash'
      $VAR1 = {
                'foo' => {}
              };
    

    【讨论】:

    • 调试时始终使用Data::Dumper
    • $Data::Dumper::Useqq=1 可能很重要;默认情况下,DD 会吐出包含肉眼无法立即识别的字符的字符串。
    【解决方案2】:

    Perl 有速记赋值运算符。 ||= 运算符通常用于设置变量的默认值,因为 Perl 具有让逻辑运算符返回最后评估的值的特性。问题是您使用了|=,这是一个按位,或者不是||=,这是一个逻辑或。

    从 Perl 5.10 开始,最好改用//=// 是逻辑定义或运算符,在当前值已定义但为 false 的极端情况下不会失败。

    【讨论】:

      【解决方案3】:

      我认为您的问题是使用“|=”(按位或赋值)而不是“||=”(如果为 false,则赋值)。

      请注意,您的新代码并不完全相同。不同之处在于“$myhash{$key} ||= {}”将用哈希引用替换现有但为假的值,但新的不会。实际上,这可能无关紧要。

      【讨论】:

        【解决方案4】:

        试试这个:

        my %myhash;
        $myhash{$key} ||= {};
        

        据我所知,您不能在my 子句中声明散列元素。你先声明哈希,然后在里面添加元素。

        编辑:我看到你删除了my。试试||= 而不是|= 怎么样?前者是“惰性”初始化的惯用语。

        【讨论】:

        • 愚蠢的我。 ||=。我责怪在其他语言中使用 Perl 休息了几个月。
        猜你喜欢
        • 2013-03-09
        • 2020-11-28
        • 2012-05-12
        • 2019-06-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-30
        • 2010-09-22
        相关资源
        最近更新 更多