Go言語マスター 〜クロージャ・フィボナッチ関数の実装〜
公開日:2022-10-15
go
はじめに
Goの条件分岐・ループ処理・条件分岐について解説します。
Function closers
Goの関数はクロージャです。
例えば次のadder
関数の例を見てみましょう。通常adder
関数が呼ばれた後はメモリ解放されるため、変数sum
は破棄されます。しかし、このadder
関数は関数を返すため、返した関数はどこかで再び呼ばれることになります。この場合sum
の値が保持されることになります。
今回の例ではsum
が保持され続け、リターンした関数に値を渡すと、sum
に数値が加算されていきます。
func adder() func(int) int {
sum := 0
return func(x int) int {
sum += x
return sum
}
}
では動作を確認してみましょう。adder
関数を2つ呼び出し、ループを行います。
func main() {
pos, neg := adder(), adder()
for i := 0; i < 10; i++ {
fmt.Println(
pos(i),
neg(-2*i),
)
}
}
結果
0 0
1 -2
3 -6
6 -12
10 -20
15 -30
21 -42
28 -56
36 -72
45 -90
pos
とneg
でそれぞれ別のメモリが確保されていることがあります。
Exercise: Fibonacci closure
フィボナッチ数列を出力するプログラムです。フィボナッチ数列とは0, 1, 1, 2, 3, 5, 8…
という、前2つの数を足したものが次の要素になる数列です。
package main
import "fmt"
func fibonacci() func() int {
f0 := 0
f1 := 1
return func() int {
x := f0
f0, f1 = f1, f0 + f1
return x
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
結果
0
1
1
2
3
5
8
13
21
34
初期値を変数f0
、f1
に入れています。クロージャの機能により変数は破棄されないので、リターンする関数が呼ばれるたびに数列の値を1つずつ計算できます。
リターンした関数はmain
内でf
に代入され、for文により10回実行されます。
おわりに
今回は、Goでのクロージャについて解説しました。関数を返す際などに、意図しない挙動を起こさないよう理解しておきましょう。