Skip to content

Golang 闭包 ​

从语义上大体可以视作“引用捕获” ——

go
x := 0

f := func() {
	x = 5
}

f()

// 此时 x = 5

比较有趣的,我们看下面例子 ——

go
func MakeCounter() func() int {
    count := 0

    return func() int {
        count++
        return count
    }
}

a := MakeCounter()
b := MakeCounter()

// 然后对 a, b 进行调用

如果用 C++ 的视角来看,这简直不可思议!—— 我们在一个闭包中“引用捕获”了一个值,那么原则上在 MakeCounter 返回的时候,这个局部变量 count 应该已经被释放了,所以在闭包中使用这个变量将会触发垂悬指针的问题

不过在 Go 中,它会保证被闭包使用的变量的生命周期延长至再也没有任何访问为止 —— 其中具体的分配信息等,可以通过下述指令进行编译器逃逸分析信息的查看

bash
go build -gcflags="-m=2" .

接着由于引用语义,所以那些 slice / map 等结构也可以理解,在闭包中修改会影响原始数据,反之亦然(虽然其实一方面是引用语义,另一方面是它本身就是一个 view 的语义二者的共同作用罢)

Released under the MIT License.