Курс по Raku / Функционално, паралелно, реактивно и уеб програмиране / Функционално програмиране / Итератори
Писане на итератор
Итераторът е просто обект, който изпълнява вградената роля
Iterator и предоставя метод pull-one. Този
метод връща следващата стойност или IterationEnd, когато не
е останало нищо. Ето итератор за обратно броене, който подава число и
крачи към нулата:
class Countdown does Iterator {
has Int $.n is rw;
method pull-one {
return IterationEnd if $!n <= 0;
return $!n--;
}
}Всяко извикване на pull-one първо проверява дали
броенето е свършило; ако не е, връща текущото число и го намалява.
Постфиксното намаляване $!n-- връща стойността
преди изваждането, така че числата излизат като
3, 2, 1. Управлението му на ръка изглежда също като при
всеки друг итератор:
my $c = Countdown.new(n => 3);
say $c.pull-one; # 3
say $c.pull-one; # 2
say $c.pull-one; # 1
say $c.pull-one =:= IterationEnd; # TrueСам по себе си итераторът не е нещо, което цикълът for
може да вземе направо — циклите очакват обхождаемо. Обвийте
итератора в Seq и той става годен за цикъл:
for Seq.new(Countdown.new(n => 3)) -> $x {
say $x;
}Това отпечатва 3, 2, 1. В
ежедневния код бихте посегнали вместо това към gather /
take — формата на генератор е далеч по-къса за същия
резултат. Все пак си струва веднъж да видите как се пише ролята
Iterator направо, защото това оголва онова, върху което са
изградени gather, map и всеки цикъл
for: обект, който отговаря на един-единствен въпрос — „коя
е следващата стойност?“.
Навигация в курса
← Тест — Протоколът на итераторите | Сума чрез pull-one →
💪 Или преминете направо към
упражнението към този раздел.