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

posted @ 2023-06-24 12:01  图兜  阅读(25)  评论(0编辑  收藏  举报