文章目录
闭包是引用了自由变量的匿名函数,被引用的自由变量和函数一同存在,即使已经离开了自由变量的环境,自由变量也不会被释放或者删除,在闭包中可以继续使用这个自由变量。函数是编译期静态的概念,而闭包是运行期动态的概念。
简单的说:函数 + 引用环境 = 闭包。
在闭包内修改引用的变量
闭包对它作用域上部变量的引用,可以进行变量修改。
package main
import (
"fmt"
)
func main() {
str := "hello world"
foo := func() {
str = "hello dude"
}
foo()
fmt.Println(str)
}
输出:
hello dude
闭包的记忆效应
被捕获到闭包中的变量让闭包本身拥有了记忆效应,闭包中的逻辑可以修改闭包捕获的变量,变量会跟随闭包的生命期一直存在。
下面是一个累加器的例子:
package main
import (
"fmt"
)
// 提供一个值,每次调用函数会对指定值进行累积
func Accumulate(value int) func() int {
// 返回一个闭包
return func() int {
value++
return value
}
}
func main() {
// 创建一个累加器,初始值为1
accumulator := Accumulate(1)
fmt.Println(accumulator())
fmt.Println(accumulator())
// 打印累加器的函数地址
fmt.Printf("%p\n", &accumulator)
// 创建一个累加器,初始值为10
accumulator2 := Accumulate(10)
fmt.Println(accumulator2())
// 打印累加器的函数地址
fmt.Printf("%p\n", &accumulator2)
}
输出:
2
3
0xc000006028
11
0xc000006038
输出的函数地址不同,可见它们是两个不同的闭包实例。