Go言語のクロージャ


Go言語で何か簡単なものを作ってみようと思い、公式サイトを見ているとフィボナッチ数列のサンプルが目にとまりました。

// fib returns a function that returns
// successive Fibonacci numbers.
func fib() func() int {
	a, b := 0, 1
	return func() int {
		a, b = b, a+b
		return b
	}
}

このサンプル、よく見るとクロージャなんですね。使い方は次のとおり。一旦、変数fに代入して呼び出している点がポイントです。

func main() {
	f := fib()
	println(f(),f(),f(),f())
}

何か作ってみたかったので再帰版の関数も追加してみました。

fibonacci.go

package main

// fib returns a function that returns
// successive Fibonacci numbers.
func fib() func() int {
	a, b := 0, 1
	return func() int {
		a, b = b, a+b
		return b
	}
}

func fib_recursive(n int) int {
	if n > 2 {
		return fib_recursive(n - 1) + fib_recursive(n - 2)
	}
	return n
}

func main() {
	f := fib() 
	f2 := fib() 
	println(f(), f(), f(), f(), f())
	println(f2(), f2(), f2(), f2(), f2())
	println(fib_recursive (1), fib_recursive (2), fib_recursive (3), fib_recursive (4), fib_recursive (5))
}

今回はメイクファイルも作ってみました。なんか久々で新鮮です。そういえば最近はmavenやらantばかりで、メイクファイルなんて10年以上書いてないなー

Makefile

#
# ARM Architecture
#
G_ARM=5g
L_ARM=5l
#
# x86, x86_32 Architecture
#
G_X86=8g
L_X86=8l
#
# AMD64, x86_64 Architecture
#
G_AMD=6g
L_AMD=6l
#
# Compiler And Linker Options
#
GFLAGS=
LFLAGS=
#
# TARGET
#
SRC=fibonacci.go
OBJ=$(SRC:%.go=%.6)
TARGET=fibonacci
#
# rules
#
%.5: %.go
	$(G_ARM) $(GFLAGS) $<

%: %.5
	$(L_ARM) $(LFLAGS) -o $@ $^

%.6: %.go
	$(G_AMD) $(GFLAGS) $<

%: %.6
	$(L_AMD) $(LFLAGS) -o $@ $^

%.8: %.go
	$(G_X86) $(GFLAGS) $<

%: %.8
	$(L_X86) $(LFLAGS) -o $@ $^

#
# 
#
all: $(TARGET)

$(TARGET): $(OBJ)

clean:
	rm $(OBJ) $(TARGET)

あわせてお読みください