11

我基本上想这样做:

foreach my $key (keys $hash_ref) {

    Do stuff with my $key and $hash_ref

    # Delete the key from the hash
    delete $hash_ref->{$key};
}

安全吗?为什么?

4

2 回答 2

19

您不是在遍历散列,而是在keys开始循环之前遍历返回的键列表。请记住,

for my $key (keys %$hash_ref) {
   ...
}

大致相同

my @anon = keys %$hash_ref;
for my $key (@anon) {
   ...
}

从哈希中删除不会导致任何问题。


each,另一方面,确实迭代了一个哈希。每次调用它时,each都会返回一个不同的元素。delete然而,它对当前元素仍然是安全的!

# Also safe
while (my ($key) = each(%$hash_ref)) {
   ...
   delete $hash_ref->{$key};
   ...
}

如果您在迭代散列时添加或删除它的元素,条目可能会被跳过或重复——所以不要这样做。例外:删除 each() 最近返回的项目总是安全的

于 2012-06-01T16:19:31.343 回答
3

这是安全的,因为keys %hash在开始迭代之前提供了整个列表一次。foreach然后继续在这个预先生成的列表上工作,不管你在实际哈希中改变了什么。

但是它会占用您的记忆,因为您会保留整个列表,直到完成为止。

于 2012-06-01T16:14:14.457 回答