闭包是一个匿名函数
一般典型的函数跟调用者沟通的方式就两种,一种是输入输出参数,一种是全局变量。
但是闭包是一种特殊的函数,可以有第三种,闭包可以access 上下文变量
func outer(name string) func() {
// variable
text := "Modified " + name
// closure. function has access to text even after exiting this block
foo := func() {
fmt.Println(text)
}
// return the closure
return foo
}
func main() {
// foo is a closure
foo := outer("hello")
// calling a closure
foo()
}
在上面的例子中, outer函数执行结束之后, 按照我们之前的理解, text这个栈变量就会被释放了,生命期结束,但是golang中没有栈变量,编译器会知道此变量还被引用,所以不会释放,继续再main函数中被access。
所以说闭包是能访问上一层『栈变量』的匿名函数
而且注意,闭包访问的是『栈变量』的引用!,什么意思,即栈变量在变化了之后, 调用闭包时,也会发现变量已经变了
C++ 11 支持 lambda, 其中capture 的变量支持引用, 如果在lambda中引用了栈变量,在范围外,就会导致undefined behavior
参考:
http://keshavabharadwaj.com/2016/03/31/closure_golang/