何为闭包
一个匿名函数引用了它的上下文对象,我们把这种状态称之为闭包。
func test(x int) func() {
println("test.x :", &x)
return func() {
println("closure.x :", &x, x)
}
}
func main() {
f := test(100)
f()
}
和匿名函数关系最深的就是闭包,因为匿名函数可以当做返回值来传。
func test() func() {
x := 1 //局部变量
fmt.Printf("%p: %v\n", &x, x) //输出地址
//返回函数
return func() {
fmt.Printf("%p: %v\n", &x, x)
}
}
func main() {
f := test()
f()
}
调用f()
,test
栈帧已经失效,但可以打印x
的值,这涉及到闭包是由两部分组成,匿名函数的指针加上环境变量的指针。很显然x
必须逃逸到堆上才能在f()
访问。因为堆上的对象和栈帧没有关系由GC来控制,这就会涉及到逃逸的问题。
$ go build -gcflags "-m -l" main.go
闭包通过指针引用环境变量
闭包严格意义上来说,由两个东西组成的,函数加上环境变量,称之为闭包。闭包有这样一个问题,比如说有一个函数,函数内部有个环境变量x&#x