Godot: Implemente o valor de retorno de yield()

Criado em 19 fev. 2015  ·  3Comentários  ·  Fonte: godotengine/godot

Para criar funções geradoras, precisamos que yield(value) seja implementado. Isso agiria como yield(), mas 'value' seria passado de volta e retornado da chamada resume().

Isso permitiria que range() fosse transformado em um iterador, em vez de criar um array potencialmente enorme.

Isso também seria um passo em direção a recursos interessantes como compreensão de lista/dit.

archived feature proposal gdscript

Comentários muito úteis

Acabei de começar a trabalhar com Godot (gostei até agora), mas concordo que parece que yield() deve ser capaz de retornar mais do que o estado da função. Yield é como retornar com a capacidade de resume(), então a função deve ser capaz de "retornar" um valor rendendo.

Uma abordagem possível que tenho pensado é aumentar o [GDScript]FunctionState
( https://docs.godotengine.org/en/3.1/classes/class_gdscriptfunctionstate.html )
ter um método value() que retorne o argumento para yield().

func co1():
     yield(5)

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

O GDscript já possui um yield que recebe dois valores e aguarda um sinal. No entanto, esta versão de um argumento apenas retornaria seu argumento no FunctionState. Com apenas essa alteração, um gerador pode ser escrito 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()

Isso funciona muito bem, mas há uma sutileza que vale a pena considerar. Quando a função corrotina retorna (em vez de render), um valor é retornado, não um FunctionState. No exemplo acima, null é retornado (porque a função é void) que testamos para parar o loop em do_stuff(). Se a função corrotina retornar um valor [ex. imagine return false no final de xrange()] então esse teste seria interrompido.

Acho que vou dar uma olhada no código.
IMO, yield(value) seria, erm, valioso.

EDIT: Olhando para o código, há complicações com a versão do sinal do yield, então a seção que escrevi abaixo sobre isso foi removida por enquanto. Pode detalhar mais tarde.

Todos 3 comentários

Solução desagradável:

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

Acabei de começar a trabalhar com Godot (gostei até agora), mas concordo que parece que yield() deve ser capaz de retornar mais do que o estado da função. Yield é como retornar com a capacidade de resume(), então a função deve ser capaz de "retornar" um valor rendendo.

Uma abordagem possível que tenho pensado é aumentar o [GDScript]FunctionState
( https://docs.godotengine.org/en/3.1/classes/class_gdscriptfunctionstate.html )
ter um método value() que retorne o argumento para yield().

func co1():
     yield(5)

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

O GDscript já possui um yield que recebe dois valores e aguarda um sinal. No entanto, esta versão de um argumento apenas retornaria seu argumento no FunctionState. Com apenas essa alteração, um gerador pode ser escrito 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()

Isso funciona muito bem, mas há uma sutileza que vale a pena considerar. Quando a função corrotina retorna (em vez de render), um valor é retornado, não um FunctionState. No exemplo acima, null é retornado (porque a função é void) que testamos para parar o loop em do_stuff(). Se a função corrotina retornar um valor [ex. imagine return false no final de xrange()] então esse teste seria interrompido.

Acho que vou dar uma olhada no código.
IMO, yield(value) seria, erm, valioso.

EDIT: Olhando para o código, há complicações com a versão do sinal do yield, então a seção que escrevi abaixo sobre isso foi removida por enquanto. Pode detalhar mais tarde.

Há alguns problemas em como yield funciona, então ele será substituído por await que é mais direto. Ainda não tenho certeza se faremos geradores reais.

Se você ainda estiver interessado na ideia de adicionar geradores, abra uma nova proposta no rastreador GIP seguindo o modelo de problema fornecido (depois de verificar se já não existe). Você pode fazer referência a esse problema e resumir as ideias da proposta. Desde já, obrigado!

Esta página foi útil?
0 / 5 - 0 avaliações