闭包环境中引用的变量是不能够在栈上分配的,而是在堆上分配。因为如果引用的变量在栈上分配,那么该变量会跟随函数f返回之后回收,那么闭包函数就不可能访问未分配的一个变量,即未声明的变量,之所以能够再堆上分配,而不是在栈上分配,是Go的一个语言特性----escape analyze(能够自动分析出变量的作用范围,是否将变量分配堆上)。
闭包的底层实现
Go在底层使用类似结构体的形式表示一个闭包。
我们可以把上面的闭包表示成这样,即:
type Closure struct{ func()() //匿名函数地址,当然语法要求一定要有变量名,这里只是为了表达匿名的含义 i *int //引用的变量地址 }
小结
-
Go语言支持闭包
-
Go语言能通过escape analyze识别出变量的作用域,自动将变量在堆上分配。将闭包环境变量在堆上分配是Go实现闭包的基础。
-
返回闭包时并不是单纯返回一个函数,而是返回了一个结构体,记录下函数返回地址和引用的环境中的变量地址。