参考:https://blog.csdn.net/qq_35976351/article/details/81986496
Golang 闭包
匿名函数
Golang支持匿名函数,即在需要使用函数时,再定义函数,匿名函数没有函数名,只有函数体。
匿名函数经常被用于实现回调函数、闭包等。匿名函数可以动态的创建,普通函数必须在包中编译前就定义完毕,而匿名函数可以随时改变功能。
func main() {
f := func(i int) {
fmt.Println(i)
}
f(10)
f = func(i int) {
fmt.Println(2 * i)
}
f(10)
}
闭包
闭包是匿名函数与匿名函数所引用环境的组合。匿名函数可以直接引用外部的变量,这就类似于普通函数直接使用全局变量一样。
func main() {
n := 0
f := func(i int) int {
n += i
return n
}
fmt.Println(f(1))
fmt.Println(f(1))
}
// output:
// 1
// 2
闭包作为函数返回值:
func increase() func(int) int {
n := 0
return func(i int) int {
n += i
return n
}
}
func main() {
f := increase()
fmt.Println(f(1))
fmt.Println(f(1))
}
// output:
// 1
// 2
并发中的闭包:
func main() {
var w sync.WaitGroup
for i := 0; i < 5; i++ {
w.Add(1)
go func() {
fmt.Println(i)
w.Done()
}()
}
w.Wait()
}
/* output:
2
5
5
5
5
原因;启动goroutine的时间要远大于循环执行的时间。
*/
一般采取以下两种方式:
- 共享的环境变量作为函数参数传递。
func main() {
var w sync.WaitGroup
for i := 0; i < 5; i++ {
w.Add(1)
go func(i int) {
fmt.Println(i)
w.Done()
}(i)
}
w.Wait()
}
/*
output:
1
0
4
2
3
*/
- 使用同名的变量保留当前的状态。
func main() {
var w sync.WaitGroup
for i := 0; i < 5; i++ {
w.Add(1)
i := i
go func() {
fmt.Println(i)
w.Done()
}()
}
w.Wait()
}
/*
output:
4
2
3
1
0
*/
**注意:**闭包会使得函数中的变量都会保存在内存中,导致内存消耗大,所以不能滥用闭包。