golang学习笔记 ---闭包补充

什么是闭包?

所谓闭包是指内层函数引用了外层函数中的变量或称为引用了自由变量的函数,其返回值也是一个函数

Go 函数可以是一个闭包。闭包是一个函数值,它引用了函数体之外的变量。 这个函数可以对这个引用的变量进行访问和赋值;换句话说这个函数被“绑定”在这个变量上。

没有闭包的时候,函数就是一次性买卖,函数执行完毕后就无法再更改函数中变量的值(应该是内存释放了);有了闭包后函数就成为了一个变量的值,只要变量没被释放,函数就会一直处于存活并独享的状态,因此可以后期更改函数中变量的值(因为这样就不会被go给回收内存了,会一直缓存在那里)。

Go里有函数类型的变量,这样,虽然不能在一个函数里直接声明另一个函数,但是可以在一个函数中声明一个匿名函数类型的变量,此时的匿名函数称为闭包(closure)

闭包的主要意义

缩小变量作用域,减少对全局变量的污染。

先看一个demo:

func f(i int) func() int {
     return func() int {
         i++
         return i
     }
}

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

 

我们再看一下效果:

package main

import (
	"fmt"
)

func f(i int) func() int {
	return func() int {
		i++
		return i
	}
}

func main() {

	c1 := f(0)
	c2 := f(0)

	fmt.Println(c1(), c2())

	for i := 1; i < 5; i++ {
		fmt.Println(c1())
	}

}

输出:c1 跟 c2 引用的是不同的环境,在调用 i++ 时修改的不是同一个 i,因此c1,c2的输出都是 1。函数 f 每进入一次,就形成了一个新的环境,对应的闭包中,函数都是同一个函数,环境却是引用不同的环境。

1 1

2

3

4

5

由此得出以下两点
1.内函数对外函数 的变量的修改,是对变量的引用
2.变量被引用后,它所在的函数结束,这变量也不会马上被烧毁

闭包函数出现的条件:
1.被嵌套的函数引用到非本函数的外部变量,而且这外部变量不是“全局变量”;
2.嵌套的函数被独立了出来(被父函数返回或赋值 变成了独立的个体),而被引用的变量所在的父函数已结束.

posted on 2020-01-10 11:15  清明-心若淡定  阅读(241)  评论(0编辑  收藏  举报