golang defer执行顺序全面详解

 更新时间:2023年09月27日 11:19:09   作者:werbenhu  
这篇文章主要为大家介绍了golang defer执行顺序全面详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

defer的执行顺序

多个defer是一个的结构,是先进后出,下面这个代码的输出顺序是CBA。

package main
import "fmt"
func main() {
    defer func1()
    defer func2()
    defer func3()
}
func func1() {
    fmt.Println("A")
}
func func2() {
    fmt.Println("B")
}
func func3() {
    fmt.Println("C")
}

defer和return的顺序

先执行return,再执行defer。

package main
import "fmt"
func deferFunc() {
    fmt.Println("defer func called")
}
func returnFunc() int {
    fmt.Println("return func called")
    return 0
}
func returnAndDefer() int {
    defer deferFunc()
    return returnFunc()
}
func main() {
    returnAndDefer()
}
// output:
// return func called 
// defer func called

函数命名返回值遇见defer

package main
import "fmt"
func foo() (t int) {
    defer func() {
        t = t * 10
    }()
    return 1
}
func main() {
    fmt.Println(foo())
}
// output: 10

defer和panic

panic阻断defer

import (
    "fmt"
)
func deferFn() {
    defer func() { fmt.Println("defer before panic 1") }()
    defer func() { fmt.Println("defer before panic 2") }()
    panic("exit")
    defer func() { fmt.Println("defer after panic") }()
}
func main() {
    deferFn()
    fmt.Println("main exit")
}
/*
output:
defer before panic 2
defer before panic 1
panic: exit
...
*/

defer里面的recover

defer在panic 后依然有效

package main
import (
    "fmt"
)
func deferFn() {
    defer func() {
        fmt.Println("defer before panic 1")
        if err := recover(); err != nil {
            fmt.Println(err)
        }
    }()
    defer func() { fmt.Println("defer before panic 2") }()
    panic("panic info")
    defer func() { fmt.Println("defer after panic") }()
}
func main() {
    deferFn()
    fmt.Println("main exit")
}
/*
output:
defer before panic 2
defer before panic 1
panic info
main exit
*/

defer中包含panic

panic仅有最后一个可以被revover捕获

package main
import (
    "fmt"
)
func main() {
    defer func() {
        if err := recover(); err != nil {
            fmt.Println(err)
        } else {
            fmt.Println("defer call")
        }
    }()
    defer func() {
        panic("defer panic")
    }()
    panic("main panic")
}
// output: defer panic

defer中函数有参数和包含子函数

package main
import "fmt"
func foo(index int, value int) int {
    fmt.Println(index)
    return index
}
func main() {
    defer foo(1, foo(3, 0))
    defer foo(2, foo(4, 0))
}
// output: 3 4 2 1

测试练习

package main
import "fmt"
func DeferFunc1(i int) (t int) {
    t = i
    defer func() {
        t += 3
    }()
    return t
}
func DeferFunc2(i int) int {
    t := i
    defer func() {
        t += 3
    }()
    return t
}
func DeferFunc3(i int) (t int) {
    defer func() {
        t += i
    }()
    return 2
}
func DeferFunc4() (t int) {
    defer func(i int) {
        fmt.Println(i)
        fmt.Println(t)
    }(t)
    t = 1
    return 2
}
func main() {
    fmt.Println(DeferFunc1(1))
    fmt.Println(DeferFunc2(1))
    fmt.Println(DeferFunc3(1))
    DeferFunc4()
}

以上就是golang defer执行顺序全面详解的详细内容,更多关于golang defer执行顺序的资料请关注脚本之家其它相关文章!

相关文章

  • 浅析Go中关于零值和空值判断的问题

    浅析Go中关于零值和空值判断的问题

    这篇文章主要是对零值和空值判断现状进行简单的梳理和分享,文中的示例代码讲解详细,对我们深入了解go语言有一定的帮助,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-08-08
  • Go语言map元素的删除和清空

    Go语言map元素的删除和清空

    本文主要介绍了Go语言map元素的删除和清空,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • 详解Go语言中的iface和eface

    详解Go语言中的iface和eface

    Go 是 Google 开发的一种编译型、并发型,并具有垃圾回收功能的编程语言,这篇文章主要介绍了Go语言中的iface和eface,需要的朋友可以参考下
    2023-07-07
  • go并发利器sync.Once使用示例详解

    go并发利器sync.Once使用示例详解

    这篇文章主要为大家介绍了go并发利器sync.Once使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • 一文带你使用golang手撸一个websocket中间件

    一文带你使用golang手撸一个websocket中间件

    这篇文章主要为大家详细介绍了如何使用golang手撸一个websocket中间件,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以参考一下
    2023-12-12
  • golang中json反序列化可能遇到的问题

    golang中json反序列化可能遇到的问题

    这篇文章主要给大家介绍了关于golang中json反序列化可能遇到的问题的解决方法,文中通过示例代码介绍的非常详细,对大家学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-01-01
  • Go语言实现百万级WebSocket连接架构设计及服务优化

    Go语言实现百万级WebSocket连接架构设计及服务优化

    本文将详细介绍如何在Go中构建一个能够支持百万级WebSocket连接的服务,包括系统架构设计、性能优化策略以及具体的实现步骤和代码示例
    2024-01-01
  • Go语言中你不知道的Interface详解

    Go语言中你不知道的Interface详解

    对于go语言来说,设计最精妙的应该是interface了,直白点说interface是一组method的组合。下面这篇文章主要给大家介绍了关于Go语言中你不知道的Interface的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。
    2018-02-02
  • 使用Go语言实现发送微信群消息

    使用Go语言实现发送微信群消息

    这篇文章主要为大家详细介绍了如何使用Go语言实现发送微信群消息,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01
  • Go 加密解密算法小结

    Go 加密解密算法小结

    加密解密在实际开发中应用比较广泛,常见的加解密分为三种,本文就详细的介绍一下Go 加密解密算法,具有一定的参考价值,感兴趣的可以了解一下
    2022-01-01

最新评论