Go 闭包的实现

本文深入探讨了Go语言中闭包的概念与实现机制,解释了闭包如何由函数及其引用环境组成,展示了闭包在Go中的具体应用实例,并讨论了闭包底层实现及变量分配策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

闭包是由函数及其相关引用环境组合而成的实体(即:闭包=函数+引用环境)。

Go中的闭包

func f() func() int {
	i:=0
	return func() int {
		i++
		return i
	}
}
复制代码

函数f返回了一个函数,返回的这个函数,返回的这个函数就是一个闭包。这个函数本身没有定义变量的,而是引用了它所在的环境(函数f)中的变量i。

         c1 := f()
	 c2 := f()
	fmt.Println(c1()) //  output: 1
	fmt.Println(c2()) //  output: 1
	fmt.Println(c2()) //  output: 2
	fmt.Println(c1()) //  output: 2
复制代码

函数f每调用一次,就形成了一个新的环境,对应的闭包中,函数都是同一个函数,环境却是引用不同的环境。

闭包环境中引用的变量是不能够在栈上分配的,而是在堆上分配。因为如果引用的变量在栈上分配,那么该变量会跟随函数f返回之后回收,那么闭包函数就不可能访问未分配的一个变量,即未声明的变量,之所以能够再堆上分配,而不是在栈上分配,是Go的一个语言特性----escape analyze(能够自动分析出变量的作用范围,是否将变量分配堆上)。

闭包的底层实现

Go在底层使用类似结构体的形式表示一个闭包。

我们可以把上面的闭包表示成这样,即:

type  Closure struct{
    func()() //匿名函数地址,当然语法要求一定要有变量名,这里只是为了表达匿名的含义
    i *int //引用的变量地址
}
复制代码

小结

  1. Go语言支持闭包

  2. Go语言能通过escape analyze识别出变量的作用域,自动将变量在堆上分配。将闭包环境变量在堆上分配是Go实现闭包的基础。

  3. 返回闭包时并不是单纯返回一个函数,而是返回了一个结构体,记录下函数返回地址和引用的环境中的变量地址。

参考:

tiancaiamao.gitbooks.io/go-internal…

转载于:https://juejin.im/post/5bb0aecef265da0ab3315dba

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值