Perl:while ($key = each %hash) 不会在 key = 0 处停止

标签 perl hash each while-loop

显然,我不需要这个;我只是好奇这里发生了什么。我失踪了吗
简单的东西?我可以在所有版本的 Perl 中依赖这种行为吗?)

Perl v5.8.8:

%h = ( 0=>'zero', 1=>'one', 2=>'two' );
while ($k = each %h) {
    $v = delete $h{$k};
    print "deleted $v; remaining: @h{0..2}\n";
}

输出
deleted one; remaining: zero  two
deleted zero; remaining:   two
deleted two; remaining:
man perlfunc (每个)都没有解释为什么
$k 时循环继续赋值为 0。
代码的行为就像 while 上的条件一样。环形
($k = each %h, defined $k) .

如果循环条件实际更改为($k = each %h, $k)那么它确实
停在 $k = 0正如预期的那样。

它也停在 $k = 0对于以下each 的重新实现:
%h = ( 0=>'zero', 1=>'one', 2=>'two' );
sub each2 {
    return each %{$_[0]};
}
while ($k = each2 \%h) {
    $v = delete $h{$k};
    print "deleted $v; remaining: @h{0..2}\n";
}

只输出:
deleted one; remaining: zero  two

最佳答案

您调用each在标量上下文中,因此由于列表返回值而无法正常工作。

就像

while ($line = <FILE>)

是添加隐式 defined 的特殊情况, 也是
while ($key = each %hash)

在 5.8.8 中,这发生在 op.c,第 3760-3766 行:
case OP_SASSIGN:
  if (k1->op_type == OP_READDIR
      || k1->op_type == OP_GLOB
      || (k1->op_type == OP_NULL && k1->op_targ == OP_GLOB)
      || k1->op_type == OP_EACH)
    expr = newUNOP(OP_DEFINED, 0, expr);
  break;

我不确定这是否适用于所有版本的 Perl 5。

另见:When does while() test for defined vs truth在 PerlMonks 上。我找不到 Perl 文档中提到的地方(提到了 <FILE> 的情况,但我没有看到 each 的情况)。

关于Perl:while ($key = each %hash) 不会在 key = 0 处停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/220879/

相关文章:

arrays - 处理每个结果时如何使用不同的起点?

perl - Perl 中的 sub _init 解释

python - 使用 join() 的方法的空间复杂度

jquery - 使用 JQuery 将哈希标签添加到当前 URL

jquery - 每个类元素的简单 jquery .hover() 方法

javascript - jQuery 克隆列表项在使用each() 函数时都获得相同的文本值

perl - 关于 perl 解包

perl - 使用 perl 创建文件夹

linux - 使用 Perl 在 linux(和 windows)上读取密码保护的 XLSX

hash - 使用迭代次数较少的 "slow"哈希函数与迭代次数较多的 "fast"哈希函数?