鉴于类似
foreach (keys %myHash) {
... do stuff ...
}
foreach (keys %myHash) {
... do more stuff ...
}
如果哈希没有改变,Perl 是否保证以一致的顺序迭代键?
是的。来自perldoc -f keys
:
密钥以明显随机的顺序返回。实际的随机顺序在 perl 的未来版本中可能会发生变化,但它保证与or函数产生的顺序相同(假设哈希没有被修改)
values
each
。从 Perl 5.8.1 开始,出于安全原因,即使在 Perl 的不同运行之间,排序也是不同的(请参阅参考资料中的“算法复杂性攻击”perldoc perlsec
)。
(强调我的)
编辑:
尽管普通散列具有一致的顺序,但在绑定散列的情况下,键的顺序没有明确定义,因为它是用户控制的!
尽管散列键顺序没有改变,但您可能应该重新考虑为什么需要这样做。
也许您可以一次处理哈希而不是两次?
作为防御性编程实践,您应该将哈希键保存到数组中,除非数据的大小足够大以至于复制它会成为问题。作为奖励,您甚至可以轻松地对列表进行排序并以明确定义的顺序在哈希中进行处理。例如,
my @keys = sort keys %myHash;
这避免了修改散列的任何问题,因为除非您愿意,否则您的数组顺序永远不会改变。
如果你不这样做,你需要非常小心,不要做任何改变哈希的事情,否则元素的顺序会改变。查看Readonly模块以确保永远不会修改此哈希。
这是一个相当冒险的期望。它可能会,但为什么要担心呢?提前获取键,保存结果,然后遍历保存的结果。然后,您可以保证以相同的顺序访问密钥。在未指定的实现细节的边缘工作是危险的。
编辑:错过了文档中的“保证”,但我仍然认为期望这永远不会改变是很危险的。尤其是当有更明智的方法来达到同样的目的时。