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反復を開始する前に、リスト全体を1回提供するため、安全です。foreachその後、実際のハッシュ内で何を変更しても、この事前に生成されたリストで作業を続けます。

ただし、完了するまでリスト全体を保持するため、メモリが消費されます。

于 2012-06-01T16:14:14.457 に答える