1.什么是闭包
1.1
简单来说,就是在一个函数内部定义另一个函数,嵌套定义,嵌套的函数一般是匿名函数。Go语言通过匿名函数来实现闭包。C++使用lambda来实现闭包。 闭包形式和表现上像函数,但不是函数,他是函数及其引用环境组合而成的实体。而函数是一些可执行的代码,函数代码一般定义后就确定,不会在执行时候发生变化,但是闭包不是,闭包在运行时可以产生多个实例。
1.2 引用环境
引用环境是指在程序执行中的某个点所有处于活跃状态的约束所组成的集合
1.3约束
约束是指一个变量的名字和其所代表的对象之间的联系
1.4闭包的本质
闭包是包含自由变量的代码块,变量不在代码块内或者任何全局上下文中定义,而是在定义代码块的环境中定义。所以只要闭包还被使用,那么自由变量以及引用的对象就不会被释放。 可以将闭包作为函数对象或者匿名函数,函数可以存储到变量之中作为参数传递给其他函数。
func add(n int) func(int) int {
sum := n
f := func(x int) int {
var i int = 2
sum += i * x
return sum
}
return f
}
add函数中函数变量为f,自由变量为sum,f为sum提供计算环境,sum和f组成的代码块就是闭包。add函数的返回值是一个闭包,而不仅仅是f函数的地址。
当分别用不同的参数(10, 20)注入add函数而得到不同的闭包函数变量时,得到的结果是隔离的,即每次调用add函数后都将生成并保存一个新的局部变量sum。
1.5总结
对象是有行为的数据,闭包是有数据的行为。
2.闭包的使用
闭包经常用于回调函数,当IO操作完成的时候,会对获取的数据进行某些操作,而操作可以交给函数对象处理。 除此之外,在一些操作中会包含一些特殊操作,可以用函数来进行封装。
2.例子
package main
import "fmt"
func adder() func(int) int {
sum := 0
f := func(x int) int {
sum += x
return sum
}
return f
}
func main() {
sum := adder()
for i := 0; i < 10; i++ {
fmt.Println(sum(i))
}
}