# Глава 7. Итераторы Итератор — это возобновляемый `proc`. Итераторы обычно используются в циклах `for`. Ранее уже были показаны встроенные итераторы `items` и `..<`. Если бы они не были встроенными, их можно было бы легко определить их самостоятельно: ```nim 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] ``` - 1 Итератор объявляется почти так же, как `proc`. Оператор `..<` принимает два целых числа и возвращает целое число. - 2 Итератор не возвращает результат, вместо этого предоставляется `yield`. Цикл `for`, вызывающий итератор `..<`, вызывает `..<` снова и снова, и каждый раз поток управления возобновляется с того места, на котором остановился итератор, до тех пор, пока не завершится цикл `while` итератора. (Когда `i >= b`.) - 3 `inc i` означает увеличение целого числа `i` на 1. Это также можно записать как `i = i + 1` или `i += 1`. - 4 Итератор `items` вызывает итератор `..<`, а итераторы вызываются в циклах `for`. ## 7.1. yield Оператор `yield` можно легко представить как разновидность оператора `return`: оператор `return` возвращает управление вызывающей стороне, потенциально возвращая значение, которое может получить вызывающая сторона: ```nim 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 ``` - 1 Вернуть значение `i` вызывающей стороне и не продолжать выполнение `find`. Это означает, что цикл `for` тоже завершается. - 2 Вернуть значение `-1`, чтобы указать, что иголка не найдена в стоге сена. - 3 Присвоить значение, возвращаемое функцией `find`, переменной `index`. `find` возвращает индекс первого вхождения `needle` в `haystack`. Невозможно возобновить выполнение функции, чтобы найти другие возможные вхождения `needle`. Это может сделать итератор, например `findAll`, благодаря ключевому слову `yield`: ```nim 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 ``` - 1 Вернуть значение `i` вызывающей стороне и продолжить выполнение `findAll` позже. - 2 Обратите внимание на отсутствие оператора `yield -1`. Если итератор не выдаст больше значений, цикл for завершится. - 3 Мы перебираем все значения, возвращаемые `findAll`, и привязываем текущее значение к индексу.