Go1.23 では、go1.22 で実験だった range-over-func 機能が実際に使用できるようになりました。サンプル コードを読んだことがある人は、そうする必要があるかもしれません。少し長い時間瞑想する。そんなことはしないでください。 P'Yod が非常に簡単に説明します。
範囲句を含む For ステートメントの仕様から始まり、3 種類の式が追加されました。
func(func() bool) func(func(V) bool) func(func(K, V) bool)
次のように説明するために変数を 1 つ追加したいと思います
f func(yield func() bool) f func(yield func(V) bool) f func(yield func(K, V) bool)
仕様によれば、関数 f を rage の式として使用する場合、関数 f を終了する前にそこで yield 関数を呼び出すたびに、各ループで結果が得られます。 yield に挿入した値と同じです。説明するとまだ混乱します。コードを書いた方が良い
func main() { for range loop { fmt.Println("-") } } func loop(yield func() bool) { yield() yield() }
出力:
- -
このようなコードを書くと、仕様に従って f で yield を 2 回呼び出すため、2 つの完全なループが得られます。ここではループという名前を付けますが、何も返しません。引数を受け入れないyieldのパターンを使用することを選択しているためです
別の例
func main() { for i := range loop { fmt.Println(i) } } func loop(yield func(int) bool) { yield(3) yield(7) }
出力:
3 7
このように、yield を 1 回呼び出したので、2 ラウンドも取得されます。range は、毎回 yield を呼び出すために使用する 3 と 7 の 2 つの値を返すようになります。
別の例
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") }
出力:
3 three 5 five 7 seven
3 つのループを取得し、毎回入力した利回りに応じて、毎回 2 つの値を取得します
また、
などの任意のタイプの引数を挿入して yield を呼び出すこともできます。
func loop(yield func(string, bool) bool) { yield("three", true) yield("five", false) yield("seven", false) }
これでその仕組みが分かりました。 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 } } } }
メイン
s := []string{"hello", "world"} for i, x := range slices.Backward(s) { fmt.Println(i, x) }
読みやすくなりましたね?結局のところ、それをどのように適用するかはあなた次第です。ここでは、yield がコールされた回数のみを確認します。範囲内に入れた場合にのみ取得できます
出てくる値は利回りに落とし込まれた値です。 以上です。
以上がGoのレンジオーバーファンクションの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。