2012-06-01 24 views

回答

15

你不是遍歷hash,你遍歷由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}; 
    ... 
} 

如果您添加或刪除哈希的元素,同時遍歷它,參賽作品可以跳過或重複的 - 所以不要做。例外:刪除最近返回的項目總是安全的()

+0

「在當前實現中」的措詞讓我感到有點恐懼,因爲聽起來像是有空間來改變實現,使得它是不再安全。我不會依賴那個,但是我不會使用'each()' - foreach鍵很好。 – LeoNerd

+0

@LeoNerd,較舊的Perl(至少5.10)只是說「它總是安全的刪除...」出於明顯的兼容性原因,我懷疑這將永遠不會被改變,而不會引入一些「使用特徵」或其他類似的附註。 –

+1

誰補充說,「在當前的實施」?它並不總是在那裏,現在不應該在那裏,除非有真正的好理由。更新:似乎不再存在。 – ysth

3

這是安全的,因爲keys %hash提供整個列表一次,然後再開始迭代。 foreach然後繼續在這個預先生成的列表上工作,而不管你在實際的哈希中改變了什麼。

雖然你吃完了你的記憶,因爲你保存完整的列表直到你完成。

相關問題