YLD — Yield

Как работает yield

YLD - Yield

На StackOverflow часто задают вопросы, подробно освещённые в документации. Ценность их в том, что на некоторые из них кто-нибудь даёт ответ, обладающий гораздо большей степенью ясности и наглядности, чем может себе позволить документация. Этот — один из них.

Вот исходный вопрос:Как используется ключевое слово yield в Python? Что оно делает? Например, я пытаюсь понять этот код (**):def _get_child_candidates(self, distance, min_dist, max_dist): if self._leftchild and distance — max_dist < self._median: yield self._leftchild if self.

_rightchild and distance + max_dist >= self._median: yield self._rightchild Вызывается он так:result, candidates = list(), [self]while candidates: node = candidates.pop() distance = node._get_dist(obj) if distance = min_dist: result.extend(node._values) candidates.extend(node.

_get_child_candidates(distance, min_dist, max_dist)) return result Что происходит при вызове метода _get_child_candidates? Возвращается список, какой-то элемент? Вызывается ли он снова? Когда последующие вызовы прекращаются?

** Код принадлежит Jochen Schulz (jrschulz), который написал отличную Python-библиотеку для метрических пространств. Вот ссылка на исходники: http://well-adjusted.de/~jrschulz/mspace/

А вот ответ:

Итераторы

Для понимания, что делает yield, необходимо понимать, что такое генераторы. Генераторам же предшествуют итераторы. Когда вы создаёте список, вы можете считывать его элементы один за другим — это называется итерацией:>>> mylist = [1, 2, 3]>>> for i in mylist :… print(i)123 Mylist является итерируемым объектом.

Когда вы создаёте список, используя генераторное выражение, вы создаёте также итератор:>>> mylist = [x*x for x in range(3)]>>> for i in mylist :… print(i)014 Всё, к чему можно применить конструкцию «for… in…

», является итерируемым объектом: списки, строки, файлы… Это удобно, потому что можно считывать из них значения сколько потребуется — однако все значения хранятся в памяти, а это не всегда желательно, если у вас много значений.

Генераторы

Генераторы это тоже итерируемые объекты, но прочитать их можно лишь один раз. Это связано с тем, что они не хранят значения в памяти, а генерируют их на лету:>>> mygenerator = (x*x for x in range(3))>>> for i in mygenerator :…

print(i)014 Всё то же самое, разве что используются круглые скобки вместо квадратных.

НО: нельзя применить конструкцию for i in mygenerator второй раз, так как генератор может быть использован только единожды: он вычисляет 0, потом забывает про него и вычисляет 1, завершаяя вычислением 4 — одно за другим.

Yield

Yield это ключевое слово, которое используется примерно как return — отличие в том, что функция вернёт генератор.>>> def createGenerator() :… mylist = range(3)… for i in mylist :… yield i*i…

>>> mygenerator = createGenerator() # создаём генератор>>> print(mygenerator) # mygenerator является объектом!>>> for i in mygenerator:… print(i)014 В данном случае пример бесполезный, но это удобно, если вы знаете, что функция вернёт большой набор значений, который надо будет прочитать только один раз.

Чтобы освоить yield, вы должны понимать, что когда вы вызываете функцию, код внутри тела функции не исполняется. Функция только возвращает объект-генератор — немного мудрёно :-) Ваш код будет вызываться каждый раз, когда for обращается к генератору.

Теперь трудная часть: В первый запуск вашей функции, она будет исполняться от начала до того момента, когда она наткнётся на yield — тогда она вернёт первое значение из цикла.

На каждый следующий вызов будет происходить ещё одна итерация написанного вами цикла, возвращаться будет следующее значение — и так пока значения не кончатся. Генератор считается пустым, как только при исполнении кода функции не встречается yield. Это может случиться из-за конца цикла, или же если не выполняется какое-то из условий «if/else».

Объяснение кода из исходного вопроса

Генератор:# Создаём метод узла, который будет возвращать генераторdef _get_child_candidates(self, distance, min_dist, max_dist): # Этот код будет вызываться при каждом обращении к объекту-генератору: # Если у узла есть потомок слева # И с расстоянием всё в порядке, возвращаем этого потомка if self._leftchild and distance — max_dist < self._median: yield self.

_leftchild # Если у узла есть потомок справа # И с расстоянием всё в порядке, возвращаем этого потомка if self._rightchild and distance + max_dist >= self._median: yield self.

_rightchild # Если исполнение дошло до этого места, генератор считается пустым Вызов:# Создаём пустой список и список со ссылкой на текущий объектresult, candidates = list(), [self] # Входим в цикл по кандидатам (в начале там только один элемент)while candidates: # Вытягиваем последнего кандидата и удаляем его из списка node = candidates.

pop() # Вычисляем расстояние между объектом и кандидатом distance = node._get_dist(obj) # Если с расстоянием всё в порядке, добавляем в результат if distance = min_dist: result.extend(node._values) # Добавляем потомков кандидата в список кандидатов, # чтобы цикл продолжал исполняться до тех пор, # пока не обойдёт всех потомков потомков кандидата candidates.extend(node.

_get_child_candidates(distance, min_dist, max_dist)) return result Этот код содержит несколько меньших частей:

  • Цикл итерируется по списку, но списко расширяется во время итерации :-) Это лаконичный способ обойти все сгрупиррованные данные, зоть это и немного опасно, так как может обернуться бесконечным циклом. В таком случае candidates.extend(node._get_child_candidates(distance, min_dist, max_dist)) исчерпает все значения генератора, но при этом продолжит создавать новые объекты-генераторы, которые будут давать значения, отличные от предыдущих (поскольку применяются к к другим узлам).
  • Метод extend() это метод объекта списка, который ожидает на вход что-нибудь итерируемое и добавляет его значения к списку.

Обычно мы передаём ему список:>>> a = [1, 2]>>> b = [3, 4]>>> a.extend(b)>>> print(a)[1, 2, 3, 4] Но в нашем коде он принимает генератор, что хорошо по следующим причинам:

  • Нет необходимости читать значения дважды.
  • Может случиться так, что потомков много и хранить их всех в памяти не хочется.

И это работает, потому что Python всё равно, является аргумент этого метода списком или нет. Python ожидает итерируемый объект, так что это сработает со строками, списками, кортежами и генераторами! Это называется утиной типизацией и является одной из причин, почему Python так крут. Но это другая история для другого вопроса… Читатель может остановиться здесь, или же прочитать ещё немного о продвинутом использовании генераторов:

Контроль за исчерпанием генератора

>>> class Bank(): # создаём банк, строящий торговые автоматы (ATM — Automatic Teller Machine)… crisis = False… def create_atm(self) :… while not self.crisis :… yield «$100″>>> hsbc = Bank() # когда всё хорошо, можно получить сколько угодно денег с торгового автомата>>> corner_street_atm = hsbc.create_atm()>>> print(corner_street_atm.

next())$100>>> print(corner_street_atm.next())$100>>> print([corner_street_atm.next() for cash in range(5)])['$100', '$100', '$100', '$100', '$100']>>> hsbc.crisis = True # пришёл кризис, денег больше нет!>>> print(corner_street_atm.next())>>> wall_street_atm = hsbc.

create_atm() # что верно даже для новых автоматов>>> print(wall_street_atm.next())>>> hsbc.crisis = False # проблема в том, что когда кризис прошёл, автоматы по-прежнему пустые…>>> print(corner_street_atm.next())>>> brand_new_atm = hsbc.create_atm() # но если построить ещё один, будешь снова в деле!>>> for cash in brand_new_atm :… print cash$100$100$100$100$100$100$100$100$100.

.. Это может оказаться полезным для разных целей вроде управления доступом к какому-нибудь ресурсу.

Ваш лучший друг Itertools

Модуль itertools содержит специальные функции для работы с итерируемыми объектами.

Желаете продублировать генератор? Соединить два генератора последовательно? Сгруппировать значения вложенных списков в одну строчку? Применить map или zip без создания ещё одного списка? Просто добавьте import itertools.

Хотите пример? Давайте посмотрим на возможные порядки финиширования на скачках (4 лошади):>>> horses = [1, 2, 3, 4]>>> races = itertools.permutations(horses)>>> print(races)>>> print(list(itertools.

permutations(horses)))[(1, 2, 3, 4), (1, 2, 4, 3), (1, 3, 2, 4), (1, 3, 4, 2), (1, 4, 2, 3), (1, 4, 3, 2), (2, 1, 3, 4), (2, 1, 4, 3), (2, 3, 1, 4), (2, 3, 4, 1), (2, 4, 1, 3), (2, 4, 3, 1), (3, 1, 2, 4), (3, 1, 4, 2), (3, 2, 1, 4), (3, 2, 4, 1), (3, 4, 1, 2), (3, 4, 2, 1), (4, 1, 2, 3), (4, 1, 3, 2), (4, 2, 1, 3), (4, 2, 3, 1), (4, 3, 1, 2), (4, 3, 2, 1)]

Понимание внутреннего механизма итерации

Итерация это процесс, включающий итерируемые объекты (реализующие метод __iter__()) и итераторы (реализующие __next__()). Итерируемые объекты это любые объекты, из которых можно получить итератор. Итераторы это объекты, позволяющие итерировать по итерируемым объектам.

Больше информации по данному вопросу доступно в статье про то, как работает цикл for.

Хабы:

Источник: https://habr.com/ru/post/132554/

Lcfvs/yld

YLD - Yield

Forget your promises, adopt the yielded programming style !

This Node.js module is under MIT License.

Concept

yld (pronounced «yielded») is a tool that keyword.

Contrary to promises, where developers add functions and disorganize their code, yld allows you to execute instructions linearly.

Each yield pauses the process and allows to retrieve a response from another function … this is comparable to promise.then().

This programming method avoids to pass the variables from scope to scope, to handle the response.

If you have already tried to use JavaScript asynchonously, you have certainly thought about some answers to these issues.

Callbacks

They often share variables needed to treat the response.

Their other inconvenients are that you have to create functions to handle the success or failure and to forward the result to calling functions. This affects the readability of your code and pollutes it with additional argument.

In order to avoid that, the promises appeared.

Promises

Promises adds a structure to manage the function result, to run functions during the execution, etc..

They are distinguished by the fact that a promise is an object though which methods you pass a whole bunch of functions to handle the execution steps.

So you end up with a lot of functions, themselves sharing internal references.

Thus puzzling your code.

The yield keyword

Reading the future ECMAScript 6 specification, I found an interesting keyword proposal : the yield.

The yield keyword si a new kind of return.

If you create a function containing one or more yield, that function returns a generator.

Note the asterisk following the function word.

The returned generator can be considered as the instruction lists contained by your function. The generator pauses at each yield until you call the next() method.

var generator, iterator; generator = function* generator(value) { var message; message = 'Hello'; yield message; yield message + ' ' + value;}; iterator = generator('World'); // writes «Hello»console.log(iterator.next()); // calls the next yield, after 2 secondssetTimeout(function () { // writes «Hello World» in your console, after the 2 seconds console.log(iterator.next());}, 2000);

In fact, yield builds a two ways communication : the first statement following yield is returned by next() and the variable passed to the second next(variable) is affected to the yield left = operand.

This allow you to send a value to the generator from the current yield and to receive a value there.

var generator, iterator; generator = function* generator() { var message, response; message = 'Hello'; response = yield message; yield message + ' ' + response;}; iterator = generator(); // writes «Hello»console.log(iterator.next()); // sends some data to the current yield point, after the 2 secondssetTimeout(function () { // sends «World» to the current yield & writes «Hello World» in your console, after the 2 seconds console.log(iterator.next('World'));}, 2000);

Finally, the generators also have a throw() method to throw an error.

The yielded programming style

Therefore, I thought it could be possible to assign to the current context (scope) variable the result of an asynchronous function and then continue the process.

Thus, yld was born.

This is a tool that allows you to transform a generator into an instruction list that run one after the other, as if it were a simple function but waiting for the response of asynchronous functions when necessary.

Moreover, it adds a relationship notion between the different scopes and allows you to avoid passing the variables from one scope to another in order to treat the response.

You can see how it works and find exemple files in the examples folder.

As you can see, this requires few functions. You only pass the arguments your function needs and, the process stops at each yield, allowing you to retrieve a value on the same line as the asynchronous function call.

Notes :

The ES6 generators are still a feature to come in JavaScript.

To use yld in Node.js, you need a Node.js version >= 0.11.x, using the —harmony flag.

To use yld in a browser :

  • install Chrome canary
  • go to chrome://flags/
  • activate Enable Experimental JavaScript
  • reboot Chrome canary
  • Enjoy

The yld function :

var yielded, iterator; yielded = yld(generator);iterator = yielded(/* closure arguments */); Function yld() Returns a yielded function used to call the closure, asynchronously Arguments : Function generator() Your function to be called, asynchronously Return : Function yielded() A function to execute your closure, with the arguments of your choice

The generator structure :

Create a step :

var generator; generator = function* () { yield; // this makes a step};

Retrieve a response form an other scope :

var generator; generator = function* () { var response; response = yield;};

The generator properties :

[FROZEN] Object this.parent

The parent yielded scope (parent.yld & parent.throw are unavailable. Each scope treats them itself)

String set this.throw(error)

Throws an error (a string or an instance of Error)

var generator; generator = function* () { this.throw('error message'); // throws the error message yield; // unreached point};

Function this.next()

Sends variables to the next yield response

var generator; generator = function* () { var response; this.next(123); response = yield; // response is 123};

Function this.nextCb()

Sends variables to the next yield response, usable to retrieve callback arguments

It's a fallback until the appearance of destructuring assignments

See how-it-works-7.js

Function this.yld()

Your this context knows yld as internal method

var generator; generator = function* () { var yielded, response; yielded = this.yld(function (/* args */) { // here, the this.parent.next() is used to send a response to the parent scope this.parent.next(123); }); response = yield yielded(/* args */); // response is 123};

Send a value after a delay :

Bind an absolute integer to generator.next() or generator.nextCb() method.

var generator; generator = function* () { var yielded, response; yielded = this.yld(function (/* args */) { var delayedNext; // here, the this.parent.next() is used to send a response to the parent scope, after a delay (2 seconds) delayedNext = this.parent.next.bind(2000); delayedNext(123); // sends the response }); response = yield yielded(/* args */); // response is 123};

Requirements :

ES6 Generators support

Источник: https://github.com/Lcfvs/yld

Оператор yield в Python 3: генераторы и return — Пример yield from

YLD - Yield

Python предоставляет программисту большой набор инструментов, один из которых — yield. Он заменяет обычный возврат значений из функции и позволяет сэкономить память при обработке большого объема данных.

yield – один из тех инструментов, использовать которые вовсе не обязательно. Всё, что можно реализовать с его помощью, можно сделать, используя обычный возврат return. Однако этот оператор позволяет не только сэкономить память, но и реализовать взаимодействие между несколькими последовательностями в пределах одного цикла.

Что такое yield и как это работает

Yield – ключевое слово, которое используется вместо return. С его помощью функция возвращает значение без уничтожения локальных переменных, кроме того, при каждом последующем вызове функция начинает своё выполнение с оператора yield.

Функция, содержащая yield в Python 3, называется генератором. Чтобы разобраться, как работает yield и зачем его используют, необходимо узнать, что такое генераторы, итераторы и итерации.

Но перед этим рассмотрим пример:

def numbers_range(n): for i in range(n): yield i a = numbers_range(4) print(type(a)) for b in a: print(b) # Выведено в консоль будет: 0 1 2 3

Тип полученного значения при вызове функции – это генератор. Один из способов получения значений из генератора – это их перебрать в цикле for. Им мы и воспользовались. Но можно его легко привести к списку, как мы сделали в статье про числа Фибоначчи.

Теперь разберемся, как это всё работает.

Что такое итерации

В программировании итерация — это процесс, в котором последовательно повторяется набор инструкций определенное количество раз или до тех пор, пока не будет выполнено условие.

Цикл — это повторяющаяся последовательность команд, каждый цикл состоит из итераций. То есть, одно выполнение цикла — это итерация. Например, если тело цикла выполнилось 5 раз, это значит, что прошло 5 итераций.

Итератор — это объект, позволяющий «обходить» элементы последовательностей. Программист может создать свой итератор, однако в этом нет необходимости, интерпретатор Python делает это сам.

Что такое генераторы

Генератор — это обычная функция, которая при каждом своём вызове возвращает объект. При этом в функции-генераторе вызывается next.

Отличие генераторов от обычной функции состоит в том, что функция возвращает только одно значение с помощью ключевого слова return, а генератор возвращает новый объект при каждом вызове с помощью yield. По сути генератор ведет себя как итератор, что позволяет использовать его в цикле for.

Программист может не использовать генераторы, однако в некоторых ситуациях оптимизировать программу можно только с их помощью.

Помимо yield, есть и другие способы создания генераторов, они описаны в статье о генераторах списка.

Функция next()

Эта функция позволяет извлекать следующий объект из итератора. То есть чтобы цикл перешел с текущей итерации на следующую, вызывается функция next(). Когда в итераторе заканчиваются элементы, возвращается значение, заданное по умолчанию, или возбуждается исключение StopItered.

На самом деле каждый объект имеет встроенный метод __next__, который и обеспечивает обход элементов в цикле, а функция next() просто вызывает его.

Функция имеет простой синтаксис: next(итератор[,значение по умолчанию]). Она автоматически вызывается интерпретатором Python в циклах while и for.

Вот пример использования next:

def numbers_range(n): for i in range(n): yield i a = numbers_range(4) print(next(a)) print(next(a)) print(next(a)) print(next(a)) # Будет выведено в консоль 0 1 2 3

Преимущества использования yield

yield используют не потому, что это определено синтаксисом Python, ведь всё, что можно реализовать с его помощью, можно реализовать и с помощью обычного return.

Программисты предпочитают применять генераторы в тех случаях, когда нет необходимости сохранять всю последовательность и промежуточные значения в памяти.

Функция, которая обрабатывает большую последовательность и использует обычный return, требует от интерпретатора выделять ей много памяти.

И если обычно такие функции не сильно влияют на производительность программы, то в проектах, содержащих последовательности с миллионами элементов, они потребляют очень много памяти.

Использование yield в языке программирования Python 3 позволяет не сохранять в память всю последовательность, а просто генерирует объект при каждом вызове функции. Это позволяет обойтись без использования большого количества оперативной памяти.

Сравнение производительности return и yield

Часто yield используют, когда необходимо прочитать большой текстовый файл. Чтобы наглядно показать преимущество использования генераторов, нужно создать два скрипта:

  • Первый использует обычный return, он читает все строки файла и заносит их в список, а затем выводит все строки в консоли.
  • Второй использует yield, он читает по одной строке и возвращает её на вывод.

Затем скрипты должны обработать несколько файлов разных размеров, при этом получаются следующие результаты:

Размер файлаreturnyield
ПамятьВремяПамятьВремя
4 Кбайт5,3 Мбайт0.023 с5,42 Мбайт0.08 c
324 Кбайт9,98 Мбайт0.028 с5,37 Мбайт0,32 с
26 Мбайт392 Мбайт27 с5.52 Мбайт29.61 с
263 Мбайт3,65 Гбайт273.56 с5,55 Мбайт292,99 с

Видно, что в обоих случаях время увеличивается с примерно одинаковой скоростью, а количество потребляемой памяти сильно различается. Чем больше обрабатываемый файл, тем заметнее различие.

yield from

Многие считают, что yield from был добавлен в язык Python 3, чтобы объединить две конструкции: yield и цикл for, потому что они часто используются совместно, как в следующем примере:

# Обычный yield def numbers_range(n): for i in range(n): yield i #yield from def numbers_range(n): yield from range(n)

Однако истинное предназначение нововведения немного в другом. Конструкция позволяет «вкладывать» один генератор в другой, то есть создавать субгенераторы.

yield from позволяет программисту легко управлять сразу несколькими генераторами, настраивать их взаимодействие и, конечно, заменить более длинную конструкцию for+yield, например:

def subgenerator(): yield 'World' def generator(): yield 'Hello' yield from subgenerator() #Запрашиваем значение из субгенератора yield '!' for i in generator(): print(i, end = ' ') # Вывод Hello World !

Как видно из примера, yield from позволяет одному генератору получать значения из другого. Этот инструмент сильно упрощает жизнь программиста, особенно при асинхронном программировании.

Заключение

Использование генераторов в правильных местах позволяет значительно уменьшить потребление памяти, кроме того, взаимодействие с генераторами более прозрачно и легче поддается отладке.

yield – это лишь одно из многих полезных средств языка Python, которое может быть без проблем заменено обычным возвратом из функции с помощью return. Оно добавлено в язык, чтобы оптимизировать производительность программы, упростить код и его отладку и дать программистам возможность применять необычные решения в специализированных проектах.

Источник: https://all-python.ru/osnovy/yield.html

Справочник по C#. Контекстное ключевое слово yield

YLD - Yield

  • 07/20/2015
  • Чтение занимает 3 мин

Использование в операторе контекстного ключевого слова yield означает, что метод, оператор или метод доступа get, в котором присутствует это ключевое слово, является итератором.

When you use the yield contextual keyword in a statement, you indicate that the method, operator, or get accessor in which it appears is an iterator.

Использование yield для определения итератора исключает необходимость применения явного дополнительного класса (в котором содержится состояние перечисления; в качестве примера см. IEnumerator) при реализации шаблонов IEnumerable и IEnumerator для пользовательского типа коллекции.

Using yield to define an iterator removes the need for an explicit extra class (the class that holds the state for an enumeration, see IEnumerator for an example) when you implement the IEnumerable and IEnumerator pattern for a custom collection type.

В следующем примере показаны две формы оператора yield.The following example shows the two forms of the yield statement.

yield return ;yield break;

Оператор yield return используется для возврата каждого элемента по одному.You use a yield return statement to return each element one at a time.

Последовательность, которая возвращается после выполнения метода итератора, можно использовать с помощью оператора foreach или запроса LINQ.The sequence returned from an iterator method can be consumed by using a foreach statement or LINQ query. Каждая итерация цикла foreach вызывает метод итератора.Each iteration of the foreach loop calls the iterator method.

При достижении в методе итератора оператора yield return возвращается expression и сохраняется текущее расположение в коде.When a yield return statement is reached in the iterator method, expression is returned, and the current location in code is retained. При следующем вызове функции итератора выполнение возобновляется с этого места.

Execution is restarted from that location the next time that the iterator function is called.

Для завершения итерации можно использовать оператор yield break.You can use a yield break statement to end the iteration.

Дополнительные сведения об итераторах см. в разделе Итераторы.For more information about iterators, see Iterators.

Методы итератора и методы доступа getIterator methods and get accessors

Объявление итератора должно соответствовать следующим требованиям.The declaration of an iterator must meet the following requirements:

Тип yield итератора, который возвращает IEnumerable или IEnumerator, — object.The yield type of an iterator that returns IEnumerable or IEnumerator is object.

Если итератор возвращает IEnumerable или IEnumerator, необходимо выполнить неявное преобразование из типа выражения в операторе yield return в параметр универсального типа.

If the iterator returns IEnumerable or IEnumerator, there must be an implicit conversion from the type of the expression in the yield return statement to the generic type parameter .

Нельзя включать инструкцию yield return или yield break:You can't include a yield return or yield break statement in:

Обработка исключенийException handling

Оператор yield return нельзя размещать в блоке try-catch.A yield return statement can't be located in a try-catch block. Оператор yield return можно размещать в блоке try оператора try-finally.A yield return statement can be located in the try block of a try-finally statement.

Оператор yield break можно размещать в блоке try или catch, но не в блоке finally.A yield break statement can be located in a try block or a catch block but not a finally block.

Если тело оператора foreach (вне метода итератора) вызывает исключение, выполняется блок finally в методе итератора.If the foreach body (outside of the iterator method) throws an exception, a finally block in the iterator method is executed.

Техническая реализацияTechnical implementation

В следующем коде возвращается объект IEnumerable из метода итератора и затем выполняется перебор его элементов.The following code returns an IEnumerable from an iterator method and then iterates through its elements.

IEnumerable elements = MyIteratorMethod();foreach (string element in elements){ …}

При вызове MyIteratorMethod тело метода не выполняется.The call to MyIteratorMethod doesn't execute the body of the method. Вместо этого вызов возвращает IEnumerable в переменную elements.Instead the call returns an IEnumerable into the elements variable.

В итерации цикла foreach метод MoveNext вызывается для elements.On an iteration of the foreach loop, the MoveNext method is called for elements. Этот вызов выполняет тело MyIteratorMethod до достижения следующего оператора yield return.This call executes the body of MyIteratorMethod until the next yield return statement is reached.

Выражение, возвращаемое оператором yield return, определяет не только значение переменной element для использования телом цикла, но и свойство Current объекта elements, представляющее собой IEnumerable.

The expression returned by the yield return statement determines not only the value of the element variable for consumption by the loop body but also the Current property of elements, which is an IEnumerable.

В каждой последующей итерации цикла foreach выполнение тела итератора продолжается с места остановки и при достижении оператора yield return оно снова останавливается.

On each subsequent iteration of the foreach loop, the execution of the iterator body continues from where it left off, again stopping when it reaches a yield return statement. Цикл foreach завершается при достижении конца метода итератора или оператора yield break.

The foreach loop completes when the end of the iterator method or a yield break statement is reached.

ПримерExample

В следующем примере имеется оператор yield return, расположенный в цикле for.The following example has a yield return statement that's inside a for loop. Каждая итерация тела оператора foreach в методе Main создает вызов функции итератора Power.

Each iteration of the foreach statement body in the Main method creates a call to the Power iterator function. При каждом вызове функции итератора происходит переход к следующему выполнению оператора yield return, которое осуществляется во время следующей итерации цикла for.

Each call to the iterator function proceeds to the next execution of the yield return statement, which occurs during the next iteration of the for loop.

Возвращаемый тип метода итератора — IEnumerable (тип интерфейса итератора).The return type of the iterator method is IEnumerable, which is an iterator interface type. При вызове метода итератора возвращается перечисляемый объект, содержащий степени числа.When the iterator method is called, it returns an enumerable object that contains the powers of a number.

public class PowersOf2{ static void Main() { // Display powers of 2 up to the exponent of 8: foreach (int i in Power(2, 8)) { Console.Write(«{0} «, i); } } public static System.Collections.Generic.IEnumerable Power(int number, int exponent) { int result = 1; for (int i = 0; i < exponent; i++) { result = result * number; yield return result; } } // Output: 2 4 8 16 32 64 128 256}

Спецификация языка C#C# language specification

Дополнительные сведения см. в спецификации языка C#.For more information, see the C# Language Specification. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.The language specification is the definitive source for C# syntax and usage.

См. такжеSee also

Источник: https://docs.microsoft.com/ru-ru/dotnet/csharp/language-reference/keywords/yield

7 отличных ETF с огромной дивидендной доходностью

YLD - Yield
7 отличных ETF с огромной дивидендной доходностью

На Уолл-Стрит более высокий риск иногда приносит более высокую прибыль.

Это наиболее очевидно в инвестициях с фиксированным доходом, которые играют на рынке облигаций, где ценные бумаги с низким уровнем риска, такие как краткосрочные и среднесрочные казначейские облигации США, приносят доход менее 1% в настоящее время, в то время как «мусорные» облигации рискованных корпораций могут приносить доход в несколько раз больше. Однако с биржевыми фондами инвесторы могут снизить некоторые из этих рисков, покупая корзину ценных бумаг вместо одной высокодоходной акции или облигации, которая может рухнуть, если что-то пойдет не так. Это, конечно, не безрисковые фонды, но с несколькими десятками холдингов и текущей доходностью более 5%.

Источник: https://zen.yandex.ru/media/id/5e7f21e35f081e20a9657423/7-otlichnyh-etf-s-ogromnoi-dividendnoi-dohodnostiu-5f55c58572b2bd46979bb09b

Все термины
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: