微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

perl – 我可以复制哈希而不重置其“每个”迭代器吗?

我正在使用每个遍历Perl哈希:
while (my ($key,$val) = each %hash) {
   ...
}

然后有趣的事情发生,我想打印出哈希.起初我考虑像:

while (my ($key,$val) = each %hash) {
   if (something_interesting_happens()) {
      foreach my $k (keys %hash) { print "$k => $hash{$k}\n" }
   }
}

但是这不会奏效,因为每个人都知道在哈希上调用密钥(或值)可以重置每个内部迭代器,我们可能会得到一个无限循环.例如,这些脚本将永远运行:

perl -e '%a=(foo=>1); while(each %a){keys %a}'
perl -e '%a=(foo=>1); while(each %a){values %a}'

没问题,我想.我可以制作哈希的副本,并打印出副本.

if (something_interesting_happens()) {
      %hash2 = %hash;
      foreach my $k (keys %hash2) { print "$k => $hash2{$k}\n" }
   }

但是这也不行.这也会重置每个迭代器.事实上,在列表上下文中使用%hash似乎重置了它的每个迭代器.所以这些也永远运行着

perl -e '%a=(foo=>1); while(each %a){%b = %a}'
perl -e '%a=(foo=>1); while(each %a){@b = %a}'
perl -e '%a=(foo=>1); while(each %a){print %a}'

这是否记录在任何地方?这是有道理的,perl可能需要使用相同的内部迭代器将哈希的内容推送到返回栈,但我也可以想象不需要这样做的哈希实现.

更重要的是,有什么办法可以做我想要的吗?要获取散列的所有元素,而不重置每个迭代器?

这也表明您无法在每次迭代中调试哈希.考虑运行调试器:

%a = (foo => 123,bar => 456);
while ( ($k,$v) = each %a ) {
    $DB::single = 1;
    $o .= "$k,$v;";
}
print $o;

只需检查调试器停止的哈希(例如,键入p%a或x%a),您将更改程序的输出.

更新:我上传Hash::SafeKeys作为这个问题的一般解决方案.感谢@gpojd指出我正确的方向和@cjm的建议,使解决方案更简单.

解决方法

你试过 Storable’s dclone来复制吗?这可能是这样的:
use Storable qw(dclone);
my %hash_copy = %{ dclone( \%hash ) };

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐