関数の中で定義した関数の事です。
関数の中で定義した関数は、外側の関数の変数を使用出来ます。
もう少し具体的に書くと関数Aの中で定義した関数Bは、関数Aのローカル変数を使用出来ます。
クロージャの例
関数の戻り値にクロージャを使用する場合
以下のように、関数の戻り値に関数を使用します。
// 関数の定義
type myFuncType func(bool) int
// クロージャの例
func getTrueCount() myFuncType {
trueCount := 0
return func(flg bool) int {
if flg == true {
trueCount++
}
return trueCount
}
}
以下のように使ってみました。
package main
import (
"fmt"
)
func main() {
// クロージャを受け取る
trueCountFnc := getTrueCount()
// 1回目のクロージャーを実行する
res := trueCountFnc(true)
fmt.Println(res) // 1 が表示される。
// 1回目のクロージャーを実行する
res = trueCountFnc(true)
fmt.Println(res) // 2 が表示される。
// 新たにクロージャを受け取る
newTrueCountFnc := getTrueCount()
// 新たに1回目のクロージャーを実行する
newRes := newTrueCountFnc(true)
fmt.Println(newRes) // 1 が表示される。
}
引数にクロージャを使用する場合
以下のように、関数の引数に関数を使用します。
// 関数の定義
type myFuncType func(string) string
// クロージャの例
func createProteinDrink(base material, myFunc myFuncType) string {
vol := "30g"
res := myFunc(vol)
return res + "作ったよ!"
}
以下のように使ってみました。
package main
import (
"fmt"
)
type material struct {
kind string
base string
}
func main() {
mate := material{
kind: "ホエイ",
base: "水",
}
res := createProteinDrink(mate, func(vol string) string {
return mate.kind + "プロテイン" + vol + "を" + mate.base + "で"
})
fmt.Println(res) // 「ホエイプロテイン30gを水で作ったよ!」が表示される
mate = material{
kind: "ソイ",
base: "牛乳",
}
res = createProteinDrink(mate, func(vol string) string {
return mate.kind + "プロテインを" + mate.base + "で"
})
fmt.Println(res) // 「ソイプロテインを牛乳で作ったよ!」が表示される
}
最後に
まだ使う場面に遭遇していないので、使うことになったら追記します。