Godot: Implementar el valor de retorno de yield()

Creado en 19 feb. 2015  ·  3Comentarios  ·  Fuente: godotengine/godot

Para crear funciones generadoras, necesitamos que se implemente yield(value). Esto actuaría como yield(), pero el 'valor' se devolvería y se devolvería desde la llamada a resume().

Esto permitiría que range() se convierta en un iterador, en lugar de crear una matriz potencialmente enorme.

Esto también sería un paso hacia características agradables como la comprensión de listas/dicciones.

archived feature proposal gdscript

Comentario más útil

Acabo de empezar a trabajar con Godot (me gusta hasta ahora) pero estoy de acuerdo en que siento que yield() debería poder devolver más que el estado de la función. El rendimiento es como regresar con la capacidad de reanudar (), por lo que la función debería poder "devolver" un valor al ceder.

Un posible enfoque en el que he estado pensando es aumentar [GDScript]FunctionState
(https://docs.godotengine.org/en/3.1/classes/class_gdscriptfunctionstate.html)
tener un método value() que devuelve el argumento a yield().

func co1():
     yield(5)

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

GDscript ya tiene un rendimiento que toma dos valores y espera una señal. Sin embargo, esta versión de un solo argumento solo devolvería su argumento en FunctionState. Con solo ese cambio, un generador podría escribirse como:

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

Esto funciona bastante bien, pero hay una sutileza que vale la pena considerar. Cuando la función coroutine devuelve (en lugar de producir), se devuelve un valor, no un estado de función. En el ejemplo anterior, se devuelve nulo (porque la función es nula), que probamos para detener el bucle en do_stuff(). Si la función coroutine devuelve un valor [ej. imagine return false al final de xrange()] entonces esa prueba se rompería.

Creo que le echaré un vistazo al código.
En mi opinión, el rendimiento (valor) sería, erm, valioso.

EDITAR: al observar el código, hay complicaciones con la versión de señal de yield, por lo que la sección que escribí a continuación se eliminó por ahora. Puede elaborar más tarde.

Todos 3 comentarios

Solución desagradable:

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

Acabo de empezar a trabajar con Godot (me gusta hasta ahora) pero estoy de acuerdo en que siento que yield() debería poder devolver más que el estado de la función. El rendimiento es como regresar con la capacidad de reanudar (), por lo que la función debería poder "devolver" un valor al ceder.

Un posible enfoque en el que he estado pensando es aumentar [GDScript]FunctionState
(https://docs.godotengine.org/en/3.1/classes/class_gdscriptfunctionstate.html)
tener un método value() que devuelve el argumento a yield().

func co1():
     yield(5)

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

GDscript ya tiene un rendimiento que toma dos valores y espera una señal. Sin embargo, esta versión de un solo argumento solo devolvería su argumento en FunctionState. Con solo ese cambio, un generador podría escribirse como:

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

Esto funciona bastante bien, pero hay una sutileza que vale la pena considerar. Cuando la función coroutine devuelve (en lugar de producir), se devuelve un valor, no un estado de función. En el ejemplo anterior, se devuelve nulo (porque la función es nula), que probamos para detener el bucle en do_stuff(). Si la función coroutine devuelve un valor [ej. imagine return false al final de xrange()] entonces esa prueba se rompería.

Creo que le echaré un vistazo al código.
En mi opinión, el rendimiento (valor) sería, erm, valioso.

EDITAR: al observar el código, hay complicaciones con la versión de señal de yield, por lo que la sección que escribí a continuación se eliminó por ahora. Puede elaborar más tarde.

Hay algunos problemas sobre cómo funciona yield , por lo que será reemplazado por await que es más sencillo. Todavía no estoy seguro de si haremos generadores reales.

Si aún está interesado en la idea de agregar generadores, abra una nueva propuesta en el rastreador GIP siguiendo la plantilla de problema proporcionada (después de verificar que aún no existe). Puede hacer referencia a este problema y resumir las ideas en la propuesta. ¡Gracias por adelantado!

¿Fue útil esta página
0 / 5 - 0 calificaciones