Go-闭包和defer
一、闭包
1、介绍:
闭包就是一个函数和与其相关的引用环境组合的一个整体(实体)
2、演示:
//累加器 func AddUpper() func(int)int{ var n int=10 return func(x int )int{ n=n+x return n } } func main(){ f:=AddUpper() //f的数据类型为func(int)int fmt.Printf(f(1)) //11 fmt.Printf(f(2)) //13 fmt.Printf(f(3)) //16 }
3、解释:
1)AddUpper是一个函数,返回值类型时func(int)int
2)构成闭包的代码如下:
var n int=10 return func(x int )int{ n=n+x return n }
返回值是一个匿名函数,但这个匿名函数引用了函数外的n,因此这个匿名函数和n形成了一个整体,构成闭包
3)可以这样理解:闭包是类,函数是操作,n是字段。 函数和它使用到的n构成闭包
4)当反复调用f函数时,因为n是初始化一次,因此每调用一次就进行累计
n变量在AddUpper调用时初始化一次,只调用了一次(即执行f :=AddUpper()时调用了一次),后续再次调用f函数,所使用到的n均来自上次调用的返回值
5)闭包的关键:分析出返回的函数引用了哪些变量。
案例:
func makeSuffix(suffix string) func(string)string{ return func(name string) string{ if strings.HasSuffix(name,suffix){ fmt.Println("该文件名包含后缀.jpg") return name }else{ fmt.Println("该文件名没有后缀,已追加") return name+suffix } } } func main(){ f :=makeSuffix(".jpg") fmt.Println(f("test.jpg")) }
案例讲解:
1)返回的匿名函数与makeSuffix(suffix string)的suffix变量组合成一个闭包,返回的函数引用到suffix变量
2)使用闭包的好处:相比传统方式实现,减少了suffix变量的传递次数,闭包可以保留上次引用的值,所以传入一次可以反复使用
二、defer
1、介绍
在函数执行完毕后,及时的释放资源
2、快速入门:
func sum(n1 int,n2 int) int { //将指令压入独立的defer栈中 //当函数执行完毕后,从defer栈中,按照先进后出的顺序出栈,依次执行 defer fmt.Println("ok1 n1=",n1) defer fmt.Println("ok2 n2=",n2) n1++
n2++ res :=n1+n2 fmt.Println("res=",res) return res } func main(){ res := sum(10,20) fmt.Println("res=",res) }
执行结果:
res= 32
ok2 n2= 20
ok1 n1= 10
res= 32
注意:在defer将语句放入栈中时,也会将相关的值拷贝入栈,eg:n1、n2