在你接触过的编程语言中,或多或少的都接触过闭包。
那什么是闭包?
闭包包含自由(未绑定到特定对象)变量;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)。“闭包” 一词来源于以下两者的结合:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域)——摘自百度
golang中的闭包
在golang中实现闭包是很简单的一件事,比如:
下面我们来分析一下这个闭包,函数closure()是一个不需要参数,返回一个类型为func(int)int类型的函数,在main()中,我们用A来接收闭包closure返回的这个func,此时就相当于A是一个func(int)int类型的函数,对A进行调用A(5),返回结果用一个x变量来接收,然后打印结果。
如果你对c语言还有一些记忆,那就知道closure()函数中的这种写法是不被允许的,原因是c在函数内,内存分配是分配在栈上的,函数closure()返回之后这部分栈空间就失效了;但是在go语言里,这里却能正常运行。我们尝试来分析一下其中的原因。
用gdb来跟踪看看有什么结果:
使用命令go build -gcflags "-N -l -m" closure
其中closure就是上面闭包的那个工程,看看打印了什么重要消息:
什么?&x escapes to heap???难怪我们对A函数的调用没出现任何问题,敢情变量x坐飞机逃到heap里面去了,这就说明go语言会自动地识别出这种情况并在堆上分配x的内存,而不是函数closure的栈上。