闭包:引用了外部变量的匿名函数。
公式:函数 + 引用外部变量 = 闭包
闭包在引用外部变量后,闭包中可以修改变量,变量会随着闭包的生命周期一直存在。
闭包的作用:
缩小变量的作用域,减少对全局变量的污染,下面的累加器如果用全局变量实现,全局变量容易被他人污染,而且要实现n个累加器就需要n个全局变量。而使用闭包,可通过accumulator1, accumulator2 := Add(1) …
使用闭包实现一个id唯一的累加器:
package main
import (
"fmt"
"sync"
"time"
)
var lock sync.RWMutex
func Add(value int) func() int {
// 返回一个闭包
return func() int {
// 上锁
lock.Lock()
defer lock.Unlock()
// 累加
value++
// 返回累加值
return value
}
}
func main() {
accumulator := Add(1)
for i:=0;i<10;i++ {
go func() {
fmt.Println(accumulator())
}()
}
time.Sleep(5*time.Second)
}
运行结果:
注意:
package main
import "fmt"
func print() []func() {
b := make([]func(), 3)
for i := 0; i < 3; i++ {
b[i] = func() {
fmt.Println(i)
}
}
return b
}
func main() {
f := print()
f[0]()
f[1]()
f[2]()
}
运行结果:
闭包引用变量i,而i最后都变成了3
改为:
func print() []func() {
b := make([]func(), 3)
for i := 0; i < 3; i++ {
b[i] = func(j int) func() {
return func() {
fmt.Println(j)
}
}(i)
}
return b
}
运行结果:
使用变量j将每次i的值记录下来