Zasadą jest użycie funkcji najlepiej dopasowanej do potrzeb.
Jeśli chcesz tylko klucze i nie planuje kiedykolwiek czytać dowolnej wartości za pomocą przycisków():
foreach my $key (keys %hash) { ... }
Jeśli chcesz tylko wartości, wartości mechanicznych():
foreach my $val (values %hash) { ... }
Jeśli potrzebujesz kluczy i wartości, użyj each():
keys %hash; # reset the internal iterator so a prior each() doesn't affect the loop
while(my($k, $v) = each %hash) { ... }
Jeśli planujesz zmienić klucze skrótu w dowolny sposób z wyjątkiem dla usunięcia bieżącego klucza podczas iteracji, to nie możesz używać każdego(). Na przykład, ten kod, aby utworzyć nowy zestaw kluczy wielkimi podwójnymi wartości działa prawidłowo za pomocą klawiszy():
%h = (a => 1, b => 2);
foreach my $k (keys %h)
{
$h{uc $k} = $h{$k} * 2;
}
produkującą oczekiwany wynikający hash:
(a => 1, A => 2, b => 2, B => 4)
Ale używając each(), aby zrobić to samo:
%h = (a => 1, b => 2);
keys %h;
while(my($k, $v) = each %h)
{
$h{uc $k} = $h{$k} * 2; # BAD IDEA!
}
daje niepoprawne wyniki w trudnych do przewidzenia sposoby.Na przykład:
(a => 1, A => 2, b => 2, B => 8)
To jednak jest bezpieczny:
keys %h;
while(my($k, $v) = each %h)
{
if(...)
{
delete $h{$k}; # This is safe
}
}
Wszystko to jest opisane w dokumentacji Perla:
% perldoc -f keys
% perldoc -f each
Proszę dodać klucze kontekstu pustki% h; przed każdą pętlą, aby bezpiecznie pokazać za pomocą iteratora. – ysth
Jest inne zastrzeżenie z każdym. Iterator jest związany z hashem, a nie z kontekstem, co oznacza, że nie jest on ponownie wprowadzany. Na przykład, jeśli zapętlisz się po hashu i wydrukujesz hash, perl wewnętrznie zresetuje iterator, tworząc pętlę bez końca: my% hash = (a => 1, b => 2, c => 3,); while (my ($ k, $ v) = każdy% hash) { wydrukuj% hash; } Przeczytaj więcej na http://blogs.perl.org/users/rurban/2014/04/do-not-use-each.html – Rawler