/
n-dimens
/
pascalabcnet
Обзор
Документация
Войти
/
n-dimens
/
pascalabcnet
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
PABCNetHelp/LangGuide/Operators/yield.html
81 строка
6 KB
samuraiGH
adding working-tree-encoding attribute (#3325)
07 ноя 2025, 16:12
Не верифицирован
07 ноя 2025, 16:12
cf1fd29
Код
Авторство
О чём код?
<html> <head> <object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e"> <param name="Keyword" value="yield"> <param name="Keyword" value="Итератор"> <param name="Keyword" value="Захват переменных в yield"> </object> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> <title></title> <link rel="StyleSheet" href="../../default.css"> </head> <body> <H1>Оператор yield</H1> <p>Оператор yield используется в функциях, генерирующих последовательности, и имеет вид:</p> <blockquote> <p><b><code>yield</code></b> <i>выражение</i></p> </blockquote> <p>Функция, содержащая yieldы, называется <em>итератором</em>. При каждом вызове такая функция выполняет код до следующего yieldа, после чего заканчивает свою работу, возвращая значение выражения, указанного в yieldе, и сохраняет своё состояние до следующего вызова. </p> <p>Например:</p> <blockquote> <p><code><strong>function</strong> Squares(n: integer): <strong>sequence</strong> <strong>of</strong> integer;<br><strong>begin</strong><br> <strong>for</strong> <strong>var</strong> i:=1 <strong>to</strong> n <strong>do</strong><br> yield i*i<br><strong>end</strong>;<br><br><strong>begin</strong><br> <strong> var</strong> q := Squares(5);<br><br> <strong>foreach</strong> <strong> var</strong> x <strong>in</strong> q <strong>do</strong><br> Print(x);<br> Println;<br><br> q.Println;<br><strong>end</strong>. </code></p> </blockquote> <p>В данном примере переменная q хранит <a href="../Types/sequences.html"> последовательность</a>, т.е. алгоритм вычисления квадратов первых n чисел, который будет запущен либо в цикле foreach по последовательности q, либо вызовом метода расширения Println для последовательности q. Данные последовательности поочередно возвращаются вызовами оператора yield в теле функции Squares.</p> <p>После каждого вызова оперматора yield функция возвращает следующее значение i*i, заканчивает свою работу и сохраняет значения всех своих переменных во внутреннем контексте. При следующем вызове этой функции её тело как бы начинает выполняться с той точки, в которой мы оказались в конце предыдущего вызова.</p> <p>В выражении yield могут фигурировать внешние относительно функции переменные. Говорят, что оператор yield осуществляет захват таких переменных. Например:</p> <blockquote> <p><code><strong>var</strong> a := 2;<br><br><strong>function</strong> Squares(n: integer): <strong>sequence of</strong> integer;<br><strong>begin</strong><br> <strong>for var</strong> i:=1 <strong>to</strong> n <strong>do</strong><br> yield i*a<br><strong>end</strong>;<br><br><strong>begin</strong><br> <strong>var</strong> q := Squares(5);<br><br> q.Println;<br> a := 3;<br> q.Println;<br><strong>end</strong>. </code></p> </blockquote> <p>В данном коде оператор yield захватывает переменную a из внешнего контекста. Захват производится по ссылке: если изменить переменную a в основной программе и повторно вызвать функцию-итератор, то при генерации последовательности будет использовано измененное значение переменной a. В итоге вывод данной программы будет иметь вид:</p> <blockquote> <p><code> 2 4 6 8 10<br>3 6 9 12 15</code></p> </blockquote> <p>Для функций, в теле которых присутствуют yield, имеется ряд ограничений:</p> <ol> <li>Функции, содержащие yield, могут возвращать только последовательности.</li> <li>Среди параметров функций-итераторов не может быть const, var, params-параметров и параметров по умолчанию.</li> <li>Если функция использует yield, в ней запрещено использовать переменную Result, и наоборот.</li> <li>Функции с yield не могут содержать операторы lock, try...except, try..finally.</li> <li>Yield не может быть вложена в оператор with.</li> <li>Yield не может быть использована внутри лямбда-выражений.</li> <li>Функции с yield не могут содержать вложенные подпрограммы и сами быть вложенными подпрограммами.</li> <li>Функции с yield не могут содержать локальные определения типов</li> <li>Методы расширения с yield не могут быть рекурсивными.</li> </ol> </body> </html>