参考: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 := 0f := func(i int) int {n += ireturn n}fmt.Println(f(1))fmt.Println(f(1))
}
// output:
// 1
// 2
闭包作为函数返回值:
func increase() func(int) int {n := 0return func(i int) int {n += ireturn n}
}
func main() {f := increase()fmt.Println(f(1))fmt.Println(f(1))
}
// output:
// 1
// 2
并发中的闭包:
func main() {var w sync.WaitGroupfor i := 0; i < 5; i++ {w.Add(1)go func() {fmt.Println(i)w.Done()}()}w.Wait()
}
/* output:25555
原因;启动goroutine的时间要远大于循环执行的时间。
*/
一般采取以下两种方式:
- 共享的环境变量作为函数参数传递。
func main() {var w sync.WaitGroupfor i := 0; i < 5; i++ {w.Add(1)go func(i int) {fmt.Println(i)w.Done()}(i)}w.Wait()
}
/*output:10423
*/
- 使用同名的变量保留当前的状态。
func main() {var w sync.WaitGroupfor i := 0; i < 5; i++ {w.Add(1)i := igo func() {fmt.Println(i)w.Done()}()}w.Wait()
}
/*output:42310
*/
**注意:**闭包会使得函数中的变量都会保存在内存中,导致内存消耗大,所以不能滥用闭包。