匿名函数和闭包
一、匿名函数
不需要定义函数名的一种函数实现方式
在需要使用函数时,再定义函数
函数可以被作为一种类型被赋值给函数类型的变量
匿名函数经常被用于实现回调函数,闭包等
1.匿名函数的定义
func(参数列表) (返回值列表) {
函数体
}
第一种:定义完成就调用
func(){}()
第二种:定义完赋值给其他函数类型的变量,直接调用函数类型的变量
a := func(){}
a()
func main() {
// 没有参数
func(){
fmt.Println("没有参数的匿名函数")
}()
// 有参数
func(a,b int){
fmt.Println(a + b)
}(1,2)
// 用参数接收
test := func(a,b int){
fmt.Println(a + b)
}
test(2,3)
// 回调函数
Adda(func(i int) {
fmt.Println(i)
})
}
func Adda(f func(i int)) {
f(1)
}
注:匿名函数本身是一种值,可以方便的保存在各种容器中实现回调函数和操作封装
2.匿名函数作为回调函数
func main() {
Add(2,3, func(a, b int) { // 回调的是Add里面的f(x,y)
fmt.Println(a + b)
})
}
func Add(x,y int, f func(a,b int)) {
f(x,y)
}
二、闭包
1.定义:
- 闭包是匿名函数与匿名函数所引用环境的组合
- 定义在一个函数内部的函数,闭包是将函数内部和函数外部连接起来的桥梁
2.特点:
- 让外部访问函数内部变量成为可能;
- 局部变量会常驻在内存中;
- 可以避免使用全局变量,防止全局变量污染;
- 有一块内存空间被长期占用,而不被释放,会造成内存泄漏
3.什么情况下才算是闭包?
- 一个外部函数,一个内部函数
- 内部函数使用了外部函数的变量(外部函数的局部变量的操作)
- 外部函数返回的是内部函数
4.示例代码:
func Add1(x int) func()int {
f := func() int{
x ++
return x
}
return f
}
func main() {
t1 := Add1(10)
fmt.Println(t1())
fmt.Println(t1())
}
结果:
11
12
13
5.闭包的作用
代码改造:
func Add2() func() {
x := 0
fmt.Println(x)
return func(x int) {
x ++
fmt.Println(x)
}
}
func main() {
f := Add2()
f()
f()
}
函数Add2内部有一个局部变量x, 为了能在外部环境中访问x,
我们让函数Add2返回了一个匿名函数,这个匿名函数有对x的访问权限,
我们在main函数调用函数Add2返回的匿名函数,可以修改并打印出x的值
当使用闭包方式访问某个局部变量时,该局部变量会常驻内存,访问速度会特别快,并且我们始终操作的都是这个变量的本身,而不是其副本,修改时也特别方便
6.使用场景:
对某一类相同的操作进行