クロージャという関数内で定義された関数があるのをご存知でしょうか?
今回クロージャをGoで実際に使うと何が便利かということを今回紹介します。
クロージャとは
クロージャーとは、関数内で定義された関数のことです。例として、関数A内で定義された関数Bは、関数A内で定義された変数を使用したり、変更することができる。この関数Bのことをクロージャと呼んでいる。
このクロージャの利点は二つある。
1つ目は、関数のスコープを制限することができる。関数Aからしか呼び出されないが、関数Aから何度も呼び出される場合、関数Bを隠して関数内の関数として使用ができる。そうすることで宣言の数が減るので、名前の衝突の危険が少なくなる。
2つ目は、関数の中で定義された変数をその環境ごと包み込んで持ち出して、関数の外でも使用することができる。
使用例
sortで使用する例.
sort.Search()の第二引数にクロージャを渡してあげて、昇順にソートすることが可能になる。
ソース
package main
import (
"fmt"
"sort"
)
func main() {
var list []int = []int{3, 5, 1, 4, 2}
fmt.Println("変更前:", list)
// 第二引数にクロージャを渡している
// main内で定義された配列のlistにアクセスできる。
sort.Slice(list, func(i, j int) bool {
return list[i] < list[j]
})
fmt.Println("変更後:", list)
}
実行結果
listがソートされて、昇順に出力されること。
変更前: [3 5 1 4 2]
変更後: [1 2 3 4 5]
関数の中で定義された変数をその環境ごと包み込んで持ち出して、関数の外でも使用する例.
関数の中で定義された変数をその環境ごと包み込んで持ち出して、関数の外でも使用することができる例として、クロージャが呼ばれる毎に、渡した値ずつ値を増やしていくincrementerを実装する。
ソース
package main
import "fmt"
// 返されるクロージャが呼ばれる毎にbaseの値分増える。
func incrementer(base int) func() int {
i := 0
return func() int {
i = i + base
return i
}
}
func main() {
oneIncrementer := incrementer(2)
for i := 0; i < 5; i++ {
// 呼ばれる毎にカウントが増えていることを確認
fmt.Println(oneIncrementer())
}
}
実行結果
2づつ数値が上がっている。
2
4
6
8
10
まとめ
今回はGoのクロージャについてまとめてみました。
この記事以外にもGoの学習ロードマップや、Goの並行処理を使うために必要な知識であるchannelやselectの仕組みについて書いた記事がありますので、そちらも読んでもらえたらと思います。
【おすすめ記事のリンク】
コメント