Go1.23 trouxe o recurso range-over-func que era um experimento no go1.22 para ser usado de verdade. Se alguém leu o código de exemplo, talvez seja necessário. medite um pouco. Não faça isso. P'Yod vai explicar de uma forma bem simples para você ler
A partir da especificação de instruções For com cláusula range, 3 tipos de expressões foram adicionados:
func(func() bool) func(func(V) bool) func(func(K, V) bool)
Gostaria de adicionar uma variável para explicar da seguinte forma
f func(yield func() bool) f func(yield func(V) bool) f func(yield func(K, V) bool)
A especificação diz que quando usamos a função f como uma expressão em raiva, toda vez que chamamos a função yield antes de terminar a função f, obtemos o resultado em cada loop. Igual ao valor que inserimos no rendimento ainda fico confuso quando explico. Melhor escrever código
func main() { for range loop { fmt.Println("-") } } func loop(yield func() bool) { yield() yield() }
saída:
- -
Se escrevermos um código como este, obteremos 2 loops completos porque chamamos yield 2 vezes em f de acordo com a especificação, aqui o nomeamos de loop e ele não retornará nada para nós. Porque optamos por usar um padrão com rendimento que não aceita nenhum argumento
Outro exemplo
func main() { for i := range loop { fmt.Println(i) } } func loop(yield func(int) bool) { yield(3) yield(7) }
saída:
3 7
Dessa forma, obteremos 2 rodadas também porque chamamos yield uma vez e agora range retornará 2 valores que são 3 e 7 que usamos para chamar yield cada vez
Outro exemplo
func main() { for i := range loop { fmt.Println(i) } } func Loop(yield func(int, string) bool) { yield(3, "three") yield(5, "five") yield(7, "seven") }
saída:
3 three 5 five 7 seven
Teremos 3 loops e obteremos 2 valores por loop de acordo com o que colocamos no rendimento de cada vez
E também podemos chamar yield inserindo qualquer tipo de argumento como
func loop(yield func(string, bool) bool) { yield("three", true) yield("five", false) yield("seven", false) }
Agora que entendemos o mecanismo disso. Quando lemos exemplos difíceis, entenderemos mais, como o exemplo no Go Wiki: Rangefunc Experiment
package slices func Backward[E any](s []E) func(func(int, E) bool) { return func(yield func(int, E) bool) { for i := len(s)-1; i >= 0; i-- { if !yield(i, s[i]) { return } } } }
principal
s := []string{"hello", "world"} for i, x := range slices.Backward(s) { fmt.Println(i, x) }
Muito mais fácil de ler, certo? No final, como aplicá-lo depende de você. Observamos apenas quantas vezes o rendimento é chamado. Você só conseguirá quando colocá-lo no alcance
O valor que sairá é o valor colocado no rendimento.
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3