Golang 入门 | 闭包

以下是个人理解:

闭包可以理解为一种保存函数状态的方法,当我们调用一个函数,或者执行操作,或者返回结果,总之当函数运行结束后,随即消亡,因为函数的声明一般是在堆上,当系统检测到当前内存空间没有被引用,那么就会回收。

闭包的作用就是保存函数的运行状态,避免内存被回收。当然会占用大量的内存。

代码说明:

package main

func main() {
	a := add()
	fmt.Println(a(1))    // 1 保存了s的值,所以当前s值为1
	fmt.Println(a(1))    // 2
	fmt.Println(a(1))    // 3

	b := add()
	fmt.Println(b(1))    // 1
	fmt.Println(b(1))    // 2
	fmt.Println(b(1))    // 3

}

func add() func(i int) int {
	s := 0               // 每次调用add函数都会生成一个s变量的内存空间,并且不会被释放。
	return func(i int) int {
		s = s + 1
		return s
	}
}

运行结果:

0xc0000b22b0 1
1
0xc0000b22b0 2
2
0xc0000b22b0 3
3
0xc0000b22b8 1
1
0xc0000b22b8 2
2
0xc0000b22b8 3
3

可以看到变量是在两个内存空间,每次调用add()都申请了一个变量s,并且在自己函数的引用空间内,s变量的值都得以保存。

上面的代码中,我们在add()函数中申请了局部变量s,那么如果我们初始化一个全局变量s,结果又如何呢?

package main

func main() {
	a := add()

	fmt.Println(a(1))     // 1
	fmt.Println(a(1))     // 2
	fmt.Println(a(1))     // 3

	b := add()
	fmt.Println(b(1))     // 4
	fmt.Println(b(1))     // 5
	fmt.Println(b(1))     // 6

}

var a = 0

func add() func(i int) int {
	return func(i int) int {
		a = a + 1
		fmt.Println(&a, a)       // 这里我们打印一下a的地址和值
		return a
	}
}

运行结果:

0x1337468 1
1
0x1337468 2
2
0x1337468 3
3
0x1337468 4
4
0x1337468 5
5
0x1337468 6
6

可以看到都是同一个内存地址,申请的s变量的内存空间被保留下来。

©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页