Godot: Implémenter la valeur de retour de yield()

Créé le 19 févr. 2015  ·  3Commentaires  ·  Source: godotengine/godot

Pour créer des fonctions génératrices, nous avons besoin que yield(value) soit implémenté. Cela agirait comme yield(), mais 'value' serait renvoyée et renvoyée par l'appel resume().

Cela permettrait à range() d'être transformé en un itérateur, plutôt que de créer un tableau potentiellement énorme.

Ce serait également un pas vers des fonctionnalités intéressantes comme la compréhension de liste/dict.

archived feature proposal gdscript

Commentaire le plus utile

Je viens de commencer à travailler avec Godot (j'aime bien jusqu'à présent) mais je suis d'accord qu'il semble que yield() devrait pouvoir renvoyer plus que l'état de la fonction. Yield est comme retourner avec la possibilité de resume() donc la fonction devrait être capable de "retourner" une valeur en cédant.

Une approche possible à laquelle j'ai pensé est d'augmenter [GDScript]FunctionState
( https://docs.godotengine.org/en/3.1/classes/class_gdscriptfunctionstate.html )
pour avoir une méthode value() qui renvoie l'argument à yield().

func co1():
     yield(5)

s = co1()
print(s.value())   # prints 5

GDscript a déjà un rendement qui prend deux valeurs et attend un signal. Cependant, cette version à un argument renverrait simplement son argument dans le FunctionState. Avec juste ce changement, un générateur pourrait être écrit comme suit :

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()

Cela fonctionne assez bien, mais il y a une subtilité à considérer. Lorsque la fonction coroutine revient (au lieu de produire), une valeur est renvoyée et non un FunctionState. Dans l'exemple ci-dessus, null est retourné (parce que la fonction est void) que nous testons pour arrêter la boucle dans do_stuff(). Si la fonction coroutine renvoie une valeur [ex. imaginez return false à la fin de xrange()] alors ce test échouerait.

Je pense que je vais regarder le code.
OMI, le rendement (valeur) serait, euh, précieux.

EDIT : En regardant le code, il y a des complications avec la version signal de yield, donc la section que j'avais écrite ci-dessous à ce sujet est supprimée pour le moment. Peut élaborer plus tard.

Tous les 3 commentaires

Solution de contournement désagréable :

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()

Je viens de commencer à travailler avec Godot (j'aime bien jusqu'à présent) mais je suis d'accord qu'il semble que yield() devrait pouvoir renvoyer plus que l'état de la fonction. Yield est comme retourner avec la possibilité de resume() donc la fonction devrait être capable de "retourner" une valeur en cédant.

Une approche possible à laquelle j'ai pensé est d'augmenter [GDScript]FunctionState
( https://docs.godotengine.org/en/3.1/classes/class_gdscriptfunctionstate.html )
pour avoir une méthode value() qui renvoie l'argument à yield().

func co1():
     yield(5)

s = co1()
print(s.value())   # prints 5

GDscript a déjà un rendement qui prend deux valeurs et attend un signal. Cependant, cette version à un argument renverrait simplement son argument dans le FunctionState. Avec juste ce changement, un générateur pourrait être écrit comme suit :

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()

Cela fonctionne assez bien, mais il y a une subtilité à considérer. Lorsque la fonction coroutine revient (au lieu de produire), une valeur est renvoyée et non un FunctionState. Dans l'exemple ci-dessus, null est retourné (parce que la fonction est void) que nous testons pour arrêter la boucle dans do_stuff(). Si la fonction coroutine renvoie une valeur [ex. imaginez return false à la fin de xrange()] alors ce test échouerait.

Je pense que je vais regarder le code.
OMI, le rendement (valeur) serait, euh, précieux.

EDIT : En regardant le code, il y a des complications avec la version signal de yield, donc la section que j'avais écrite ci-dessous à ce sujet est supprimée pour le moment. Peut élaborer plus tard.

Il y a quelques problèmes sur le fonctionnement yield , il sera donc remplacé par await qui est plus simple. Je ne sais pas encore si nous ferons de vrais générateurs.

Si vous êtes toujours intéressé par l'idée d'ajouter des générateurs, veuillez ouvrir une nouvelle proposition sur le tracker GIP en suivant le modèle de problème donné (après avoir vérifié qu'il n'existe pas déjà). Vous pouvez faire référence à ce problème et résumer les idées dans la proposition. Merci d'avance!

Cette page vous a été utile?
0 / 5 - 0 notes