Почему не делает Perl, которого каждый () выполняет итерации через весь хеш во второй раз?

Просто спросите себя: "действительно ли это - исключительный случай, которым не найден объект"? Если это, как ожидают, произойдет в нормальном ходе Вашей программы, Вы, вероятно, не должны повышать исключение (так как это не исключительное поведение).

Короткая версия: используйте исключения, чтобы обработать исключительное поведение, не обработать нормальный поток управления в Вашей программе.

- Alan.

6
задан brian d foy 14 July 2009 в 21:30
поделиться

2 ответа

каждый использует указатель, связанный с хешем, чтобы отслеживать итерацию. Он не знает, что первый цикл while отличается от второго цикла while, и сохраняет между ними один и тот же указатель.

Большинство людей избегают каждого по этой (и другим) причинам, вместо этого выбирая keys :

for my $key (keys %hash){
    say "$key => $hash{$key}";
}

Это также дает вам контроль над порядком итераций:

for my $key (sort keys %hash){
    say "$key => $hash{$key}";
}

В любом случае, если вы собираетесь завершить цикл раньше, избегайте каждый .

BTW , сторонники функционального программирования должны воспользоваться этой возможностью, чтобы указать на недостатки скрытого состояния. То, что выглядит как операция без сохранения состояния («цикл по каждой паре в таблице»), на самом деле имеет состояние с сохранением состояния.

18
ответ дан 8 December 2019 в 03:40
поделиться

вы можете прочитать perldoc на каждом

perldoc -f each

. Когда хэш полностью прочитан, в контексте списка возвращается нулевой массив (который при назначении дает ложь (0) value) и undef в скалярном контексте. Следующий вызов "each" после этого снова начнет повторяться. Есть грех gle-итератор для каждого хэша, общий для всех вызовов функций "each", "keys" и "values" в программе; его можно сбросить считывая все элементы из хэша, или оценивая «ключи HASH» или «значения HASH».

поэтому вы можете использовать ключи%, установленные в вашем коде, для повторной итерации (из-за вашего «последнего» оператора)

print "Iterate upto ggg...\n";
while ( my ($key, $val) = each %set ) {
    print "$key -> $val \n";
    last if ($val eq 'ggg');
}
print "\n";
keys %set;
print "Iterate All...\n";
while ( my ($key, $val) = each %set ) {
    print "$key -> $val \n";
}
print "\n";
10
ответ дан 8 December 2019 в 03:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: