🦸
Go言語でクロージャーを使う
Go by Example: Closures
公式の解説を翻訳しております
Goはクロージャを形成できる匿名関数をサポートしています。無名関数は、名前を付けずにインラインで関数を定義したい場合に便利です。
このintSeq関数は、intSeq本体の中で匿名で定義した別の関数を返す。返された関数は変数iを閉じてクロージャーを形成する。
intSeqを呼び出し、その結果(関数)をnextIntに代入する。この関数値は、nextIntを呼び出すたびに更新されるi値をキャプチャする。
nextIntを数回呼び出して、クロージャーの効果を確認する。
その状態が特定の関数に固有のものであることを確認するには、新しい関数を作ってテストする。
関数の最後の機能は再帰だ
package main
import "fmt"
// func intSeq() func() intは、intSeq()から新しい関数を返します。
// これが、再帰的に呼び出されることにより、クロージャを形成します。
// ここでのクロージャは、それ自体の値を保持している関数です。
// クロージャーとは、それ自体の環境を持つ関数値です。
func intSeq() func() int {
// iはintSeqに属するローカル変数のように振る舞います。
i := 0
// intSeqは、intSeqの中で定義された無名関数を返します。
return func() int {
// intSeqの中で定義された無名関数は、iという変数にアクセスします。
i++
return i
}
}
func main() {
// intSeqを呼び出し、その戻り値(関数)をnextIntに代入します。
nextInt := intSeq()
fmt.Println(nextInt())
fmt.Println(nextInt())
fmt.Println(nextInt())
// intSeqから別の関数を新たに作成し、そこからnextIntに代入します。
newInts := intSeq()
fmt.Println(newInts())
}
実行結果
hashimotojunichi@hashimotojunichinoMacBook-Pro go-example % go run hello.go
1
2
3
1
まとめ
今回使った匿名関数とは、プログラミング言語の世界では、名前のない関数のことです。
goのクロージャは、このように関数の中で定義された無名関数です。
再帰関数という表現も聞きますが、よく使われるのは再帰という表現です。
Discussion