Курс по Raku / Функционално, паралелно, реактивно и уеб програмиране / Функционално програмиране / Итератори
Протоколът на итераторите
Всяка стойност, която можете да обходите в цикъл — списък, диапазон,
масив, — може да ви подаде итератор чрез метода
.iterator. Итераторът има един съществен метод —
pull-one, — който връща следващата стойност всеки път,
когато го извикате:
my $it = (10, 20, 30).iterator;
say $it.pull-one; # 10
say $it.pull-one; # 20
say $it.pull-one; # 30Когато стойностите свършат, pull-one връща специален
страж — IterationEnd, — вместо истински елемент. Заявката
за още една стойност от същия $it го показва:
say $it.pull-one =:= IterationEnd; # TrueОператорът =:= проверява за същия обект
и точно така разпознавате стража. Тази подробност има значение вътре в
цикъл, където трябва и да запазите изтеглената стойност, и да я
проверите. Ако я присвоите с =, стойността
попада в контейнер и сравнението разглежда контейнера, а не
IterationEnd. Лекарството е да свържете с
:=, така че променливата просто да бъде онова,
което pull-one е върнал:
my $it = <a b c>.iterator;
loop {
my $v := $it.pull-one; # свързване, а не присвояване
last if $v =:= IterationEnd;
say $v;
}Цикълът отпечатва a, b, c и
спира. Точно това прави цикълът for за вас под капака: той
извиква .iterator върху онова, което обхождате, и
продължава да вика pull-one, докато не срещне
IterationEnd. Рядко ви се налага да го изписвате на ръка,
но щом го направите веднъж, се вижда, че Raku всъщност обхожда
итератори, а не списъци.
Практика
Направете 1 тест върху съдържанието на тази тема.
Навигация в курса
← Итератори | Тест — Протоколът на итераторите →
💪 Или преминете направо към
упражнението към този раздел.