Golang

关注公众号 jb51net

关闭
首页 > 脚本专栏 > Golang > Go语言 defer和panic执行顺序

深入理解Go语言中defer和panic的执行顺序

作者:纸鸢666

defer 和 panic 的执行顺序是一个重要的概念,本文主要介绍了Go语言中defer和panic的执行顺序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

简介

在 Go 语言中,defer 和 panic 的执行顺序是一个重要的概念。本文将通过一个示例代码来详细解释为什么 defer 中的代码会先执行,而 panic 的错误信息稍后才输出。

示例代码

package main

import "fmt"

func mayPanic() {
    panic("a problem")
}

func main() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered. Error:\n", r)
        }
    }()

    mayPanic()

    fmt.Println("After mayPanic()")
}

执行顺序解释

1. defer 的执行机制

defer 的作用是延迟执行一个函数调用,直到包含它的函数执行完毕。无论函数是正常结束还是因为错误(如 panic)结束,所有被 defer 延迟的函数都会按照后进先出(LIFO)的顺序执行。

2. panic 的传播机制

当 panic 被触发时,Go 会立即中断当前函数的正常执行流程,并开始向上层调用栈传播错误信号。在这个过程中,Go 会依次执行当前函数中所有被 defer 延迟的函数。这些延迟函数可以通过 recover() 捕获并处理 panic。

3. 代码执行顺序

(1) 执行 main() 函数

func main() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered. Error:\n", r)
        }
    }()

    mayPanic()  // 触发 panic
    fmt.Println("After mayPanic()")  // 这行代码不会执行
}

(2) 调用 mayPanic()

func mayPanic() {
    panic("a problem")
}

panic("a problem") 被触发,程序会立即中断当前函数的执行,并将 panic 信息传播到上层调用栈。

(3) 触发 defer 延迟函数

由于 panic 的触发,Go 会开始执行 main() 函数中被 defer 延迟的函数:

defer func() {
    if r := recover(); r != nil {
        fmt.Println("Recovered. Error:\n", r)
    }
}()

在这个延迟函数中,recover() 被调用,捕获了 panic 的错误信息 "a problem",并打印出来。

(4) panic 被恢复

由于 recover() 成功捕获了 panic,程序的正常执行流程得以恢复。不过,panic 的传播已经中断了 main() 函数的正常执行,因此 fmt.Println("After mayPanic()") 不会执行。

4. 输出结果顺序

按照以上执行顺序,程序的输出如下:

Recovered. Error:
 a problem

为什么 defer 先执行?

这是因为 panic 的传播机制会触发所有 defer 延迟函数的执行。defer 的设计初衷是确保某些重要的清理操作(如释放资源、关闭文件等)能够在函数结束时执行,即使函数是因 panic 而异常结束的。

总结来说:

总结

通过上述代码和解释,我们可以清楚地看到 defer 和 panic 的执行顺序是由 Go 语言的设计规则决定的。defer 确保了清理操作的执行,而 panic 的传播机制允许我们在延迟函数中捕获并处理错误。

到此这篇关于Go语言中defer和panic的执行顺序的文章就介绍到这了,更多相关Go语言 defer和panic执行顺序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文