在Perl中,当我循环同一个散列时,从散列引用中删除一个键安全吗?为什么?
我基本上想这样做:在Perl中,当我循环同一个散列时,从散列引用中删除一个键安全吗?为什么?,perl,hash,key,Perl,Hash,Key,我基本上想这样做: foreach my $key (keys $hash_ref) { Do stuff with my $key and $hash_ref # Delete the key from the hash delete $hash_ref->{$key}; } 安全吗?为什么呢?这是安全的,因为在开始迭代之前,keys%hash只提供一次完整的列表foreach然后继续处理这个预生成的列表,不管您在实际哈希中做了什么更改 但它会占用您的内存,
foreach my $key (keys $hash_ref) {
Do stuff with my $key and $hash_ref
# Delete the key from the hash
delete $hash_ref->{$key};
}
安全吗?为什么呢?这是安全的,因为在开始迭代之前,
keys%hash
只提供一次完整的列表foreach
然后继续处理这个预生成的列表,不管您在实际哈希中做了什么更改
但它会占用您的内存,因为您会保留整个列表,直到完成为止。您不是在迭代散列,而是在开始循环之前迭代由
键返回的键列表。记住
for my $key (keys %$hash_ref) {
...
}
大致与
my @anon = keys %$hash_ref;
for my $key (@anon) {
...
}
从散列中删除不会产生任何问题
另一方面,它对哈希进行迭代。每次调用时,每个
都返回一个不同的元素。但是,删除当前元素仍然是安全的
# Also safe
while (my ($key) = each(%$hash_ref)) {
...
delete $hash_ref->{$key};
...
}
如果您在对散列进行迭代时添加或删除散列的元素,则可能会跳过或复制条目——所以不要这样做。例外:删除每个()最近返回的项总是安全的
“在当前实现中”的措辞让我有点害怕,因为听起来好像有空间改变实现,使其不再安全。我不相信这一点,但我也不会使用each()
——foreach键很好。@LeoNerd,旧的Perl(至少5.10)只是说“删除总是安全的…”出于明显的兼容性原因,我怀疑如果不引入一些使用特性或其他类似的术语,这一点将永远不会改变。谁添加了这一点“在当前的实现中”?它并不总是存在,现在也不应该存在,除非有非常好的理由。更新:似乎不再存在。啊。在中添加,在中删除