登录
首页 >  Golang >  Go教程

Golangdefer执行顺序与栈机制详解

时间:2025-07-01 09:35:22 401浏览 收藏

大家好,我们又见面了啊~本文《Golang defer执行顺序与栈结构解析》的内容中将会涉及到等等。如果你正在学习Golang相关知识,欢迎关注我,以后会给大家带来更多Golang相关文章,希望我们能一起进步!下面就开始本文的正式内容~

defer在Go中的执行顺序是后进先出(LIFO),1.遇到defer语句时,函数调用会被压入栈中,2.当前函数返回前,栈顶的defer函数依次弹出执行;例如连续两个defer,后写的先执行。defer参数在注册时求值,如i++不影响已保存的值。return前会执行defer,可能影响命名返回值的结果。注意事项包括:避免循环中频繁使用defer、不在defer中做耗时操作、注意作用域及副作用。

Golang defer关键字的执行顺序 结合栈结构解释延迟调用机制

在 Golang 中,defer 是一个非常实用的关键字,用来延迟执行某个函数调用,通常用于资源释放、锁的释放等场景。但很多人刚接触时会对其执行顺序感到困惑,尤其是当多个 defer 出现的时候。

Golang defer关键字的执行顺序 结合栈结构解释延迟调用机制

其实,只要理解 defer 的底层机制是基于栈结构实现的,它的执行顺序就很容易理解了。

Golang defer关键字的执行顺序 结合栈结构解释延迟调用机制

defer 的执行顺序是后进先出(LIFO)

Golang 在遇到 defer 语句时,并不会立即执行对应的函数,而是将其压入一个函数调用栈中。等到当前函数即将返回之前,才会从栈顶开始依次弹出并执行这些被推迟的函数调用。

举个简单的例子:

Golang defer关键字的执行顺序 结合栈结构解释延迟调用机制
func main() {
    defer fmt.Println("first")
    defer fmt.Println("second")
    fmt.Println("hello world")
}

输出结果是:

hello world
second
first

虽然两个 defer 是按顺序写的,但由于它们被压入栈中,执行顺序就是反过来的。这和我们日常理解的“最后写的先执行”是一致的。


defer 与函数参数求值时机

一个容易忽略的细节是:defer 后面的函数参数是在 defer 被执行时就完成求值的,而不是等到真正执行该函数时才计算。

看个例子:

func demo() {
    i := 0
    defer fmt.Println(i)
    i++
}

这段代码输出的是 0,不是 1。因为 i 的值在 defer 执行时就已经确定为 0 了,后续的 i++ 并不会影响已经保存下来的值。

所以记住一点:defer 注册时就完成了参数求值


defer 与 return 的关系

很多人以为 return 之后就不能再执行 defer 了,实际上并不是这样。Go 在函数返回前,会先处理所有注册好的 defer 调用,然后再真正退出函数。

例如:

func f() int {
    var i int
    defer func() {
        i++
    }()
    return i
}

这个函数返回的其实是 1,而不是 0。因为 return i 的值已经被准备好了,但在返回前执行了 defer,修改了 i 的值。

这种情况说明:defer 可以影响带命名返回值的函数的结果


使用 defer 的一些注意事项

  • 不要在循环中频繁使用 defer,可能会导致性能问题。
  • 避免在 defer 中做耗时操作,因为它会影响函数的返回速度。
  • defer 的作用域是函数级别的,不能跨函数传递。
  • 如果 defer 函数有副作用(比如修改变量),要特别小心它的执行顺序。

总的来说,理解 defer 的执行顺序并不难,关键在于它背后的“栈结构”机制。掌握了这一点,很多看似奇怪的行为其实都合情合理。

基本上就这些,不复杂但容易忽略。

今天带大家了解了的相关知识,希望对你有所帮助;关于Golang的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~

相关阅读
更多>
最新阅读
更多>
课程推荐
更多>