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

最后我发现我的问题就在于:

$myhash{$key} |= {};

也就是说,“分配$ myhash {$ key}对空哈希的引用,除非它已经有值”。

取消引用它并尝试将其用作哈希引用,导致使用字符串作为哈希引用的解释器错误。

将其更改为:

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

......让事情奏效。

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

任何人都可以解释一下吗?

有帮助吗?

解决方案

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

  $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' => {}
          };

其他提示

Perl有速记赋值运算符。 || = 运算符通常用于设置变量的默认值,因为Perl的逻辑运算符返回最后一个值。问题是您使用 | = 这是按位或代替 || = 这是一个逻辑

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

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

请注意,您的新代码并不完全等效。不同之处在于“ $ myhash {$ key} || = {} &quot;将使用哈希引用替换现有但错误的值,但新的值不会。在实践中,这可能不相关。

试试这个:

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

据我所知,您无法在 my 子句中声明哈希元素。首先声明哈希,然后在中添加元素。

编辑:我看到你已经取出了 my 。如何尝试 || = 而不是 | = ?前者是“懒惰”的惯用词。初始化。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top