func fib() func() int {
var n1, n2 int
return func() int {
if n1 == 0 && n2 == 0 {
n1 = 1
} else {
n1, n2 = n2, n1 + n2
}
return n2
}
}
next := fib()
for i := 0; i < N; i++ {
fmt.Printf("F%d\t= %4d\n", i, next())
}
- First class functions(Go语言中函数是一等公民,函数就像变量,可以赋值,传参,作为返回值)
- 上面的函数的返回值是一个函数(将函数想象成一种类型)
- “闭包”,意思是它是完整独立的,仅仅依靠调用时参数求值,不再依赖调用时的上下文
- 函数是没有状态的,加入了闭包以后就变成有状态的了,相对于一个有成员变量的类实例来说,闭包中的状态值不是自己管理,可以认为是『上帝』在管理
- 闭包就像一个行走的对象
观察上面的函数,其实只有两条语句,第一条声明了两个变量n1和n2,第二条返回了一个函数。重要的是这个作为fib返回值的函数的返回值是该条返回语句之前声明的变量。说起来有点绕。本来n1和n2在函数返回之后应该释放,但是返回的匿名函数的返回值又需要这俩变量,所以不能释放。所以导致的结果就是,这两个变量没有被释放,被存起来了,并且随着闭包函数的执行而改变。
fib函数创造了一个函数next,将next想象成一个拥有n1, n2成员变量的对象。