关于Go的闭包、匿名函数和defer的结合使用案例分析

本文通过一个具体的案例深入探讨了Go语言中defer关键字的使用方法及其常见的陷阱,特别是当defer与匿名函数结合使用时的行为表现。文章还展示了如何利用defer进行资源清理,并解释了其先进后出的执行顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Go里的“析构函数”defer关键字类似于PHP的__destruct(),用来标记最后执行的Go语句,一般用在资源释放、关闭连接等操作,会在函数关闭前调用。多个defer的定义与执行类似于栈的操作:先进后出,最先定义的最后执行。在defer的使用中,碰到过许多坑,尤其是在defer与匿名函数搭配使用的时候,厦门用一个案例分析下。

package main

import (
    "fmt"
)

func main() {
    var fs = [4]func(){} //声明一个function类型的slice,长度为4

    for i := 0; i < 4; i++ {
        defer fmt.Println("defer i= ", i)                       //这是一个i作为参数传进去的输出,因为i是int型,所以遵循一个规则值拷贝的传递,还有defer是倒序执行的,所以先后输出3,2,1,0,跟下面的defer交替执行4次
        defer func() { fmt.Println("defer_closure i = ", i) }() //执行完下面的代码后,到了该defer了,这也是一个匿名函数,同样的也没有参数,也没有定义i,所以这也是个闭包,用的也是外面的i,所以先输出4,接着执行上面的defer,这样反复执行4次
        fs[i] = func() { fmt.Println("closure i = ", i) }       //把相应的4个匿名函数存到function类型的slice里,因为这是个匿名函数,又没有参数,且也没有定义i,所以i就是外层函数的地址引用,就是for循环的i的地址,执行完for后i的值为4,所以输出4个4
    }

    for _, f := range fs { //用for循环对slice的调用,f为slice的值,即匿名函数,而f()则是对匿名函数的调用
        f()
    }
}



输出:

  closure i =  4
  closure i =  4
  closure i =  4
  closure i =  4
  defer_closure i =  4
  defer i=  3
  defer_closure i =  4
  defer i=  2
  defer_closure i =  4
  defer i=  1
  defer_closure i =  4
  defer i=  0


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值