2012-06-01 13 views

risposta

15

Non stai iterare su l'hash, il gioco è iterazione sulla lista delle chiavi restituite da keys prima ancora di iniziare il ciclo perché

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

è più o meno lo stesso di

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

L'eliminazione dall'hash non causa alcun problema.


each, dall'altro, fa iterare su un hash. Ogni volta che viene chiamato, each restituisce un elemento diverso. Eppure, è ancora sicuro di delete l'elemento corrente!

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

Se si aggiungono o eliminano gli elementi di un hash, mentre l'iterazione su di esso, le voci possono essere saltati o ripetuti - in modo da non farlo. Eccezione: è sempre sicuro eliminare l'elemento più recente restituito da ciascuno()

+0

La dicitura "nell'implementazione corrente" mi spaventa un po ', perché sembra che ci sia spazio lì per cambiare l'implementazione in modo tale che sia non è più sicuro. Non mi affiderei a questo, ma non userò neanche 'each()' - le chiavi foreach vanno bene. – LeoNerd

+0

@LeoNerd, vecchio Perl (almeno 5.10) basta dire "È sempre sicuro cancellare ..." Per ovvi motivi di compatibilità, dubito che questo sarà mai cambiato senza introdurre alcune "funzioni d'uso" o altri pragma simili. –

+1

chi ha aggiunto che "nell'attuale implementazione"? non era sempre lì, e non dovrebbe esserci ora, a meno che non ci sia davvero una buona ragione. aggiornamento: non sembra esserci più. – ysth

3

È sicuro, perché keys %hash fornisce l'intero elenco una volta, prima di iniziare l'iterazione. foreach continua quindi a lavorare su questo elenco pre-generato, indipendentemente da ciò che si modifica all'interno dell'hash reale.

Mangia la tua memoria però, perché mantieni l'intero elenco finché non lo fai.

Problemi correlati