Go でイテレータを構築する慣用的な方法
チャネルは、反復のためのチャネルのようなメカニズムを提供します。 goroutine リークの危険を冒さずに反復から抜け出すことができないなどの制限はありますが、Go で反復子パターンを作成する慣用的な方法ではありません。この目的には、クロージャの方が適切です。
package main import "fmt" func main() { gen := newEven() fmt.Println(gen()) fmt.Println(gen()) fmt.Println(gen()) gen = nil // release for garbage collection } func newEven() func() int { n := 0 // closure captures variable n return func() int { n += 2 return n } }
別のオプションは、メソッドで名前付き型を使用することです。
package main import "fmt" func main() { gen := even(0) fmt.Println(gen.next()) fmt.Println(gen.next()) fmt.Println(gen.next()) } type even int func (e *even) next() int { *e += 2 return int(*e) }
Go のファーストクラス関数により、ジェネレータの連鎖は簡単です。以下に例を示します。
package main import "fmt" func main() { gen := mapInt(newEven(), square) fmt.Println(gen()) fmt.Println(gen()) fmt.Println(gen()) gen = nil // release for garbage collection } type intGen func() int func newEven() intGen { n := 0 return func() int { n += 2 return n } } func mapInt(g intGen, f func(int) int) intGen { return func() int { return f(g()) } } func square(i int) int { return i * i }
結論として、Go でイテレータを作成する手法は複数ありますが、慣用的なアプローチにはクロージャまたはメソッドを備えた名前付き型が含まれます。どちらを選択するかは、特定のニーズとトレードオフによって異なります。
以上がGo でイテレータを作成する最も慣用的な方法は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。