【容易踩坑】golang中的defer

1 defer解释

defer是Go语言中的一个关键字,用于延迟执行函数调用。当一个函数中使用了defer关键字来延迟执行某个函数调用时,该函数调用会被推迟到函数返回之前执行。

defer常用于需要在函数返回之前执行一些清理或释放资源的操作,例如关闭文件、释放锁等。defer还可以用于捕获函数中的错误,并在函数返回之前进行处理。

2 defer注意点

在使用defer时,需要注意以下几点:

  1. defer后面必须跟一个函数调用,可以是普通函数、匿名函数或方法。
  2. defer的函数调用参数会在defer语句执行时被计算,但是函数调用本身不会被执行。
  3. 多个defer语句会按照逆序执行,即最后一个defer语句会最先执行,倒数第二个defer语句会倒数第二个执行,以此类推。
  4. defer语句中的函数调用可以修改函数的返回值。当函数中存在多个defer语句时,最后一个执行的defer语句可以修改函数的返回值。

3 简单例子

演示了defer的用法和如何修改返回值:

package main

import "fmt"

func main() {
    result := calculate()
    fmt.Println(result) // 输出: 6
}

func calculate() int {
    num := 3

    defer func() {
        num *= 2 // 修改返回值
    }()

    return num
}

在上面的示例中,calculate()函数中的defer语句中的匿名函数会在calculate()函数返回之前执行。在匿名函数中,我们将num的值乘以2,从而修改了函数的返回值。

需要注意的是,defer语句中的函数调用对函数的返回值只是进行了一次修改,而不会对后续的返回值产生影响。因此,如果在defer语句之后还有其他的返回语句,那么这些返回语句的返回值不会受到defer的影响。

4 执行顺序问题

package main

import "fmt"

func main() {
    defer fmt.Println("First defer")
    defer fmt.Println("Second defer")
    defer fmt.Println("Third defer")
    fmt.Println("Hello, World!")
}

在上面的示例中,我们使用了三个defer语句,分别打印了"First defer"、“Second defer"和"Third defer”。在main()函数中,我们还打印了"Hello, World!"。

// 输出结果
Hello, World! 
Third defer 
Second defer 
First defer

可以看到,"Hello, World!“是第一个打印出来的,而三个defer语句则按照逆序执行,最后一个defer语句"Third defer"最先执行,倒数第二个defer语句"Second defer"次之,最后是第一个defer语句"First defer”。

这个示例说明了多个defer语句的执行顺序是逆序的,最后一个defer语句会最先执行,倒数第二个defer语句会倒数第二个执行,以此类推。这种逆序执行的特性可以用于一些需要在函数返回之前进行的清理操作,例如关闭文件、释放资源等。

5 执行顺序复杂例子

func calc(index string, a, b int) int {
   ret := a + b
   fmt.Println(index, a, b, ret)
   return ret
}

func main() {
   a := 1
   b := 2
   defer calc("1", a, calc("10", a, b))
   a = 0
   defer calc("2", a, calc("20", a, b))
   b = 1
}

猜猜正确的执行顺序?
公布正确结果

10 1 2 3
20 0 2 2
2 0 2 2
1 1 3 4
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值