Итератор — это возобновляемый proc. Итераторы обычно используются в циклах for.
Ранее уже были показаны встроенные итераторы items и ..<. Если бы они не были встроенными, их можно было бы легко определить их самостоятельно:
iterator `..<`(a, b: int): int = # 1
var i = a
while i < b:
yield i # 2
inc i # 3
iterator items(s: seq[Point]): Point =
for i in 0 ..< s.len: # 4
yield s[i]
proc. Оператор ..< принимает два целых числа и возвращает целое число.yield. Цикл for, вызывающий итератор ..<, вызывает ..< снова и снова, и каждый раз поток управления возобновляется с того места, на котором остановился итератор, до тех пор, пока не завершится цикл while итератора. (Когда i >= b.)inc i означает увеличение целого числа i на 1. Это также можно записать как i = i + 1 или i += 1.items вызывает итератор ..<, а итераторы вызываются в циклах for.Оператор yield можно легко представить как разновидность оператора return: оператор return возвращает управление вызывающей стороне, потенциально возвращая значение, которое может получить вызывающая сторона:
proc find(haystack: string; needle: char): int =
for i in 0 ..< haystack.len:
if haystack[i] == needle: return i # 1
return -1 # 2
let index = find("abcabc", 'c') # 3
i вызывающей стороне и не продолжать выполнение find. Это означает, что цикл for тоже завершается.-1, чтобы указать, что иголка не найдена в стоге сена.find, переменной index.find возвращает индекс первого вхождения needle в haystack. Невозможно возобновить выполнение функции, чтобы найти другие возможные вхождения needle. Это может сделать итератор, например findAll, благодаря ключевому слову yield:
iterator findAll(haystack: string; needle: char): int =
for i in 0 ..< haystack.len:
if haystack[i] == needle: yield i # 1
# 2
for index in findAll("abcabc", 'c'): discard # 3
i вызывающей стороне и продолжить выполнение findAll позже.yield -1. Если итератор не выдаст больше значений, цикл for завершится.findAll, и привязываем текущее значение к индексу.