【go语言】defer 延迟执行

defer 关键字将其后的语句推迟到所在函数返回之前执行,常用于资源释放:关闭文件、解锁、关闭连接等。

1. 基本用法

func readFile(path string) {
    f, err := os.Open(path)
    if err != nil {
        return
    }
    defer f.Close() // 无论函数从哪里返回,Close 都会执行

    // ... 读写文件
}

把 Close 和 Open 写在相邻位置,不容易因为中途 return 或 panic 而忘记释放资源。

2. 执行顺序:后进先出

一个函数中可以有多个 defer,它们按声明顺序的逆序执行,类似栈:

func main() {
    defer fmt.Println(1)
    defer fmt.Println(2)
    defer fmt.Println(3)
}
// 输出:3 2 1

3. 参数值在 defer 语句时确定

defer 语句执行时,函数的参数会立即求值并复制,不会等到实际执行时:

i := 0
defer fmt.Println("defer:", i) // 此刻 i 的值 0 已被复制
i = 10
// 函数结束输出:defer: 0

// 如果希望拿到最终值,用闭包引用变量
i = 0
defer func() { fmt.Println("defer:", i) }()
i = 10
// 输出:defer: 10

4. defer 与返回值

命名返回值可以在 defer 中被修改:

func f() (result int) {
    defer func() {
        result++ // 修改了命名返回值
    }()
    return 1 // 实际返回 2
}

匿名返回值则不受影响,因为 return 时值已经复制出去。defer 中修改返回值是 double check、资源清理记录日志等场景的基础,但也会降低可读性,不要滥用。

5. defer 与 recover

defer 中的函数可以配合 recover 捕获 panic,这是 Go 语言恢复程序运行的唯一手段,下一节错误处理会详细展开。

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容