全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-13 6 分钟 ✍️ juanwangdev

Go延迟执行defer

defer语句延迟函数执行到函数返回前,常用于资源清理。

defer基本用法

基本语法

Go
func readFile() {
    file, err := os.Open("data.txt")
    if err != nil {
        return
    }
    defer file.Close()  // 函数返回前执行

    // 读取文件...
}

多个defer

Go
func process() {
    defer fmt.Println("1")
    defer fmt.Println("2")
    defer fmt.Println("3")

    fmt.Println("执行")
}

// 输出顺序:
// 执行
// 3
// 2
// 1

多个defer按声明顺序逆序执行(栈结构)。

defer执行时机

函数返回前

Go
func example() int {
    defer fmt.Println("defer执行")
    fmt.Println("函数体")
    return 10
}

// 输出顺序:
// 函数体
// defer执行

return之后

Go
func example() int {
    defer fmt.Println("defer")
    return 10
    // return之后执行defer
}

defer参数评估

参数立即评估

Go
func example() {
    i := 1
    defer fmt.Println(i)  // 参数i在此时已确定为1
    i++
    fmt.Println("函数内:", i)  // 2
}

// 输出:
// 函数内: 2
// defer: 1  // defer打印1,参数已评估

defer参数在声明时评估,不是执行时。

闭包捕获变量

Go
func example() {
    i := 1
    defer func() {
        fmt.Println(i)  // 闭包捕获i,执行时打印2
    }()
    i++
}

// 输出:
// defer: 2  // 执行时才取i的值

defer与返回值

命名返回值影响

Go
func example() (n int) {
    defer func() {
        n++  // 可修改命名返回值
    }()
    return 10
}

fmt.Println(example())  // 11

非命名返回值不影响

Go
func example() int {
    n := 10
    defer func() {
        n++  // 修改局部变量,不影响返回值
    }()
    return n  // 返回10
}

fmt.Println(example())  // 10

defer常见用途

资源释放

Go
func process() {
    mu.Lock()
    defer mu.Unlock()  // 确保释放锁

    // 处理...
}

文件关闭

Go
func read() {
    file, _ := os.Open("data.txt")
    defer file.Close()

    // 读取...
}

错误恢复

Go
func safeProcess() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("恢复:", r)
        }
    }()

    panic("出错")
}

打印调试

Go
func trace(name string) func() {
    fmt.Println("进入:", name)
    return func() {
        fmt.Println("退出:", name)
    }
}

func process() {
    defer trace("process")()
    // 处理...
}

defer执行顺序图

text
┌─────────────────────────────────────┐
│     函数体执行                        │
│                                      │
│     defer A  →  压入栈               │
│     defer B  →  压入栈               │
│     defer C  →  压入栈               │
│                                      │
│     return                           │
└─────────────────────────────────────┘
              ↓
┌─────────────────────────────────────┐
│     defer栈弹出执行                  │
│                                      │
│     C → B → A(逆序)                 │
└─────────────────────────────────────┘

defer特性总结

特性说明
执行时机函数返回前
执行顺序逆序(栈)
参数评估声明时评估
闭包捕获执行时取值
命名返回值可修改
非命名返回值不可修改

要点总结

  • defer延迟执行到函数返回前
  • 多defer逆序执行(栈结构)
  • defer参数声明时立即评估
  • 闭包defer执行时才取变量值
  • defer可修改命名返回值
  • 常用于资源释放、错误恢复
  • defer紧跟资源获取语句

📝 发现内容有误?点击此处直接编辑

← 上一篇 Go匿名函数与闭包
下一篇 → Go错误处理与panic/recover
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库