Golang——defer

本文深入探讨了Go语言中的defer机制,解释了其在函数执行过程中的作用,如何确保资源的正确释放。通过实例展示了defer语句的压栈和后进先出执行顺序,并分析了带有返回值的defer函数中return、return value与defer的执行顺序。内容包括defer的基本使用、注意事项与调用顺序的实际应用,有助于理解Go语言的这一关键特性。

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

目录

注意事项与细节

defer的调用顺序


在函数中,程序员经常需要创建资源(比如:数据库连接、文件句柄、锁等) ,为了在函数执行完毕后,及时的释放资源,Go 的设计者提供 defer (延时机制)。

package main
import "fmt"
func sum(n1 int,n2 int) int {
    defer fmt.Println("ok1 n1=",n1)
    defer fmt.Println("ok2 n2=",n2)//注意n1,n2的输出顺序,遵守出栈规则
    res := n1 + n2
    fmt.Println("ok3 res=",res)
    return res
}
func main() {
    res := sum(10,20)
    fmt.Println("res=",res)
}

输出结果:

ok3 res= 30
ok2 n2= 20
ok1 n1= 10
res= 30

注意事项与细节

  1. 当 go 执行到一个 defer 时,不会立即执行 defer 后的语句,而是将 defer 后的语句压入到一个栈中, 然后继续执行函数下一个语句。

  2. 当函数执行完毕后,在从该栈中,依次从栈顶取出语句执行(遵守栈 先入后出的机制),

  3. 在 defer 将语句放入到栈时,也会将相关的值拷贝同时入栈

  4. defer 允许你把配套的两个行为代码放在最近相邻的两行,比如创建&释放资源、加锁&释放锁等,使得代码更易读,编程体验优秀。

defer的调用顺序

package main
import "fmt"
func deferFunc1(i int) (t int) {
    t = i
    defer func() {
        t += 1
    }()
    return t
}
func deferFunc2(i int) int {
    t := i
    defer func() {
        t += 1
    }()
    return t
}
func deferFunc3(i int) (t int) {
    defer func() {
        t += i
    }()
    return 1
}
func deferFunc4() (t int) {
    defer func(i int) {
        fmt.Println(i)
        fmt.Println(t)
    }(t)
    t = 0
    return 1
}
func main() {
  // 猜猜下面输出的内容和顺序
    fmt.Println(deferFunc1(1)) 
    fmt.Println(deferFunc2(1))
    fmt.Println(deferFunc3(1))
    deferFunc4()
}

defer是延迟函数,执行动作在return之后,defer相当于是将执行动作压入栈中,越是后面的defer越是先执行,执行顺序是LIFO(后进先出)

特别指出:有函数返回值的则return将结果写入返回值,defer进行收尾,可以看做 return最先执行,然后return将结果存入返回值,最后defer执行

那么基于刚刚的介绍再回头去看得到的『实际结果是:2,1,2,0,1』

  • defer,return,return value(函数返回值) 执行顺序:首先return,其次return value,最后defer。defer可以修改函数最终返回值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值