一 、定义:
闭包:要有一个需要保护的局部变量+一个匿名函数
二、闭包的两种写法:
1. 在主函数之外定义一个闭包函数,闭包函数的格式为:
func 函数名 func() int{
res = func() int{
......
}
return res
}
举例一:
package main import "fmt" func main() { //主函数始终存在对add2的引用,因此只要主函数没被关闭,gc就不会回收add2中的s res := add2() //此时,res的实质是函数 res = func(int)int fmt.Printf("res = %T", res) for i := 0; i < 10;i++ { fmt.Printf("i=%d ", i) sum := res(i) //res既然是个函数,那么传入对应的参数即可。 fmt.Println(sum) } } func add2() func(int)int{ s := 0 res := func(i int) int{ s += i return s } return res }
举例二:
package main import "fmt" func main() { res := counter() //先看看res的类型 fmt.Printf("%T \n", res) //func() int //再看看res的值 fmt.Printf("res=%d \n", res) //res=4771872 //最后看看res()的值 fmt.Printf("res()=%d \n",res()) //res()=1 注意思考这里为什么是1 fmt.Println("res():", res()) //res()=2 注意思考这里为什么是2 fmt.Println("res():", res())//res()=3 注意思考这里为什么是3 fmt.Println("res():", res())//res()=4 注意思考这里为什么是4 //现在再赋给一个变量res2,注意观察它的内存地址与值 fmt.Printf("res=%d \n", res) //res=4771872 //最后看看res()的值 fmt.Printf("res()=%d \n",res()) //res()=5 注意思考这里为什么是1 fmt.Println("res():", res()) //res()=6 注意思考这里为什么是2 res2 := counter() fmt.Printf("res2:",res2) //4774192 fmt.Println("res2():" , res2()) fmt.Println("res2():" , res2()) fmt.Println("res2():" , res2()) } //用闭包实现counter功能,并注意观察各类类型 //闭包的步骤:1. 在函数中写一个匿名函数“func() 返回值类型{}”,并用一个变量接受 // 2. 返回匿名函数 // 3. 在主方法中用变量接收函数counter.其实也就是接收闭包函数 func counter() func() int{ i := 0 res := func() int{ i += 1 return i } //注意观察这里的res其实是个地址 fmt.Printf("Counter中的res=%d \n" , res) //Counter中的res=4771872 return res }
2. 闭包的另一种省略写法:
直接在主函数中定义一个闭包:
res := func() (func() int){
return func() int{
}
}()
举例一:
package main import "fmt" func main() { /** 闭包另一种省略写法 1. 定义一个匿名闭包函数,这个闭包函数是没有参数的,但一定有返回值,返回一个匿名函数 2. 定义内部的匿名函数,内部的匿名函数一定要与返回的匿名函数类型一致 3. 返回刚刚定义的匿名函数 4. 匿名函数的用法:在声明的时候就调用必须在后面加上() 综上所述,闭包写法为: res := func() (func() int){ }() */ res := func () (func() int){ i := 10 return func() int{ i++ return i } }() fmt.Println(res) //这样输出来的是地址 fmt.Println(res()) //res()代表运行闭包中的函数 }