概念
闭包是能读取其它函数内部变量的函数,它是一个定义在一个函数内部的函数,它建立起了函数内部和函数外部变量的桥梁
作用
在函数外,我们如果想对某些函数内部的变量进行某些操作,那么该怎么办?有一种方法是,定义一个全局变量,然后在函数内部使用这个全局变量,这样在函数外就可以使用到这个变量了
不过你想一下,如果为了对函数内的某些变量进行操作而去定义一个全局变量,那么这个是不太好的,因为全局变量的作用范围太大了,不好掌控。
而使用闭包之后,可以在函数调用过程中隐式传递要被操作的变量
示例
什么是闭包?代码说明
package main
import "fmt"
func externalFunc(count int) func() int{
return func() int {
count++
return count
}
}
func main() {
// 这时候的external是个函数,externalFunc函数返回了个匿名函数
external := externalFunc(1) // 这时候的count == 1
fmt.Println(external()) //输出2
}
我们定义了一个externalFunc()函数,这个函数需要返回一个匿名函数,这个函数内部使用到外部函数的参数 count,这个时候,我们就可以说这个函数是闭包函数了
那么从代码中,我们可以得出什么是闭包函数,一个函数里面的内部函数引用了内部函数外的变量,那么我们就可以认为这个函数是闭包函数了(我自己都觉得这个理由,有点儿牵强...)
内部函数引用外部函数的变量的情况
在这里,我们把定义的那个函数称为外部函数,外部函数里面的函数,称为内部函数
package main
import "fmt"
func externalFunc(count int) func() int{
return func() int {
count++
return count
}
}
func main() {
// 这时候的external是个函数,externalFunc函数返回了个匿名函数
external := externalFunc(1) // 这时候的count == 1
fmt.Println(external()) //输出2
fmt.Println(external()) //输出3
fmt.Println(external()) //输出4
}
输出
2
3
4
啊?为什么输出的是2,3,4呢?
这是因为,当闭包函数引用外部变量的时候,会把这个变量放在堆中,当我们上面调用了externalFunc(1)之后,生成了一个函数,赋值给了external,这时候,因为count变量在堆中,所以count = 1;而后面又调用了内部函数,又执行了一次count++,所以输出了count = 2...以此类推
如果我们多次调用外部函数的情况
package main
import "fmt"
func externalFunc(count int) func() int{
return func() int {
count++
return count
}
}
func main() {
// 这时候的external是个函数,externalFunc函数返回了个匿名函数
external := externalFunc(1) // 这时候的count == 1
external2 := externalFunc(1) // 这时候的count == 1
external3 := externalFunc(1 )// 这时候的count == 1
fmt.Println("external:", external()) // 这时候的count == 2
fmt.Println("external2:", external2()) // 这时候的 count == 2
fmt.Println("external3:", external3()) // 这时候的 count == 2
}
输出
external: 2
external2: 2
external3: 2
啊这,怎么都输出2呢?
这是因为啊,每次调用外部函数的时候,那么返回的多个闭包所引用的外部变量会生成多个副本给它们使用
扩展,无代码
闭包引用全局变量的情况跟上面的内部函数引用外部函数的变量的情况的情况是一样的,只要你使用一次闭包,那个全局变量的值都会改变,因为全局变量的作用范围大,当你调用一次闭包后,这个全局变量并不会被释放掉,而且这个全局变量也是放在堆中的
欢迎大家关注下个人的「公众号」:独醉贪欢