Чтобы создать функции генератора, нам нужно реализовать yield(value). Это будет действовать как yield(), но 'value' будет передано обратно и возвращено из вызова restore().
Это позволило бы превратить range() в итератор, а не создавать потенциально огромный массив.
Это также было бы шагом к приятным функциям, таким как понимание списка/слова.
Неприятный обходной путь:
func xrange(count, dict):
var i = 0
while i < count:
dict.next = i
yield()
i += 1
func do_stuff():
var curr = {}
var it = xrange(5, curr)
while curr.value != null:
print(curr.value)
it.resume()
Я только начал работать с Godot (пока мне это нравится), но я согласен с тем, что yield() должен возвращать больше, чем состояние функции. Yield подобен возврату с возможностью возобновления(), поэтому функция должна иметь возможность «возвращать» значение, уступая.
Один из возможных подходов, о котором я думал, это расширение [GDScript]FunctionState.
( https://docs.godotengine.org/en/3.1/classes/class_gdscriptfunctionstate.html )
иметь метод value(), который возвращает аргумент yield().
func co1():
yield(5)
s = co1()
print(s.value()) # prints 5
GDscript уже имеет yield, который принимает два значения и ожидает сигнала. Однако эта версия с одним аргументом просто вернет свой аргумент в FunctionState. Только с этим изменением генератор можно было бы написать так:
func xrange(count):
var i = 0
while i < count:
yield(i)
func do_stuff():
var it = xrange(5)
while it:
print(it.result())
it = it.resume()
Это работает довольно хорошо, но есть тонкость, которую стоит учитывать. Когда функция сопрограммы возвращает значение (вместо получения), возвращается значение, а не FunctionState. В приведенном выше примере возвращается null (поскольку функция недействительна), что мы проверяем, чтобы остановить цикл в do_stuff(). Если функция сопрограммы возвращает значение [например. представьте return false
в конце xrange()], тогда этот тест не сработает.
Думаю посмотрю код.
ИМО, доходность (стоимость) была бы, хм, ценной.
РЕДАКТИРОВАТЬ: Глядя на код, есть сложности с сигнальной версией yield, поэтому раздел, который я написал ниже об этом, на данный момент удален. Может уточнить позже.
Есть некоторые проблемы с тем, как работает yield
, поэтому он будет заменен на await
, что более прямолинейно. Я еще не уверен, будем ли мы делать настоящие генераторы.
Если вы все еще заинтересованы в добавлении генераторов, пожалуйста, откройте новое предложение на трекере GIP, следуя заданному шаблону задачи (предварительно убедившись, что он еще не существует). Вы можете сослаться на этот вопрос и обобщить идеи в предложении. Заранее спасибо!
Самый полезный комментарий
Я только начал работать с Godot (пока мне это нравится), но я согласен с тем, что yield() должен возвращать больше, чем состояние функции. Yield подобен возврату с возможностью возобновления(), поэтому функция должна иметь возможность «возвращать» значение, уступая.
Один из возможных подходов, о котором я думал, это расширение [GDScript]FunctionState.
( https://docs.godotengine.org/en/3.1/classes/class_gdscriptfunctionstate.html )
иметь метод value(), который возвращает аргумент yield().
GDscript уже имеет yield, который принимает два значения и ожидает сигнала. Однако эта версия с одним аргументом просто вернет свой аргумент в FunctionState. Только с этим изменением генератор можно было бы написать так:
Это работает довольно хорошо, но есть тонкость, которую стоит учитывать. Когда функция сопрограммы возвращает значение (вместо получения), возвращается значение, а не FunctionState. В приведенном выше примере возвращается null (поскольку функция недействительна), что мы проверяем, чтобы остановить цикл в do_stuff(). Если функция сопрограммы возвращает значение [например. представьте
return false
в конце xrange()], тогда этот тест не сработает.Думаю посмотрю код.
ИМО, доходность (стоимость) была бы, хм, ценной.
РЕДАКТИРОВАТЬ: Глядя на код, есть сложности с сигнальной версией yield, поэтому раздел, который я написал ниже об этом, на данный момент удален. Может уточнить позже.