Golang | 对闭包的一些个人理解
Posted Parker@1989
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 s = 0
func add() func(i int) int
return func(i int) int
s = s + 1
fmt.Println(&s, s) // 这里我们打印一下a的地址和值
return s
运行结果:
0x1337468 1
1
0x1337468 2
2
0x1337468 3
3
0x1337468 4
4
0x1337468 5
5
0x1337468 6
6
可以看到都是同一个内存地址,申请的s变量的内存空间被保留下来。
以上是关于Golang | 对闭包的一些个人理解的主要内容,如果未能解决你的问题,请参考以下文章
经典js闭包----对《大部分人都会做错的经典JS闭包面试题》的理解