Курс 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 →
💪 Або перейдіть одразу до вправи
цього розділу.