Курс 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 тест за змістом цієї теми.
Навігація курсом
← Ітератори | Тест — Протокол ітератора →
💪 Або перейдіть одразу до вправи
цього розділу.