2010-09-28 60 views
15

我想完全重置我的%hash,以便它根本不包含鍵或值。我更喜歡使用單線程而不是必須使用循環。如何在不使用for循環的情況下完全重置哈希?

到目前爲止,我曾嘗試:

%hash = 0; 
%hash = undef; 

但這些都拋在警告嚴格模式啓用錯誤,所以我寫了一個簡單的for循環來實現同樣的事情:

for (keys %hash) { 
    delete $hash{$_}; 
} 

這但是我真的很想用一行代碼來做到這一點。有沒有辦法簡單地重置我忽略的散列?

+9

我很驚訝,沒有人有沒有提出的問題已經工作。 AFAICR我從來沒有需要重置哈希,因爲使用Perl可以有非常緊湊的範圍。我讓變量簡單地落在範圍之外;如果在循環中,會在頂部附近使用「my」創建新的詞彙。 - 我認爲這是一個XY算法改進的空間,也許給出更多的上下文? – daxim 2010-09-28 10:45:07

+0

散列是我在所有檢查和平衡之後在我的程序開始附近創建的全局。它用不同的子程序修改,直到我將最終版本分配到一個數組中。考慮到這個流程,除非我錯過了某些東西,否則我認爲在將它分配給數組之後「重置」這個特定的散列比使用'my'語句重新創建它更容易。 (有可能我忽略了一個XY問題,因爲我不知道如何做類似重置哈希的操作) – Structure 2010-09-29 02:14:48

回答

35

%hash =();undef %hash;都可以工作,區別在於後者會給出一些內存用於其他事情。前者會將記憶保存在之前使用的哈希中,假設它將在以後再次使用,當哈希被重新填充時。

您可以使用Devel::Peek觀察到的行爲:

$ perl -MDevel::Peek -we'my %foo = (0 .. 99); %foo =(); Dump \%foo; undef %foo; Dump \%foo' 
SV = IV(0x23b18e8) at 0x23b18f0 
    REFCNT = 1 
    FLAGS = (TEMP,ROK) 
    RV = 0x23acd28 
    SV = PVHV(0x23890b0) at 0x23acd28 
    REFCNT = 2 
    FLAGS = (PADMY,SHAREKEYS) 
    ARRAY = 0x23b5d38 
    KEYS = 0 
    FILL = 0 
    MAX = 63 
    RITER = -1 
    EITER = 0x0 
SV = IV(0x23b18e8) at 0x23b18f0 
    REFCNT = 1 
    FLAGS = (TEMP,ROK) 
    RV = 0x23acd28 
    SV = PVHV(0x23890b0) at 0x23acd28 
    REFCNT = 2 
    FLAGS = (PADMY,SHAREKEYS) 
    ARRAY = 0x0 
    KEYS = 0 
    FILL = 0 
    MAX = 7 
    RITER = -1 
    EITER = 0x0 

PVHV S中的MAX字段是重要的一點。

+0

感謝您的額外見解。我希望我的哈希將不會包含相同的值,當它被重新填充,所以我會利用undef%散列;句法。 – Structure 2010-09-28 07:45:36

+11

這不是真正關於哈希中存儲了什麼值,而是關於它們中有多少。分配,釋放,然後再分配一些內存以將值存儲在散列中並不是最快的事情,因此perl會假設散列最終會再次增長到原始大小,即使它用「 %h =()',並且保持需要的內存來存儲散列中的許多元素,除非明確要求不這樣做。這不會與你在hash中佔用的實際值的內存混淆。 – rafl 2010-09-28 07:51:06

+0

現在我看到了區別。好的,我將不得不使用Devel :: Peek來查看哪些對我的用例更有效。 – Structure 2010-09-28 09:46:06

2

使用

%hash =(); 
+2

在那裏使用'my',實際上是創建一個與現有的哈希無關的新哈希,而不是清理掉舊的散列。 – cjm 2010-09-28 07:31:15

+0

現在糾正 – Thariama 2010-09-28 07:34:41

5

您可以使用undef

undef %hash; 
1

%hash =();必須努力

0

由於OP問了一個襯墊,與使用嚴格和警告

delete $hash{$_} for (keys %hash) 
相關問題