Z
ZHANK
编程在线教程Go 教程defer/panic/recover
函数

defer/panic/recover

defer 延迟执行(LIFO)、panic 恐慌、recover 捕获、何时用

defer/panic/recover

defer 保证函数退出前执行(类似 finally 但更灵活),panic 是"不可恢复的错误",recover 捕获 panic。

学完本章你将: 掌握 defer LIFO、panic/recover、典型使用场景。


defer —— 延迟执行

go
package main

import "fmt"

func main() {
    defer fmt.Println("第一")   // LIFO:最后声明的最先执行
    defer fmt.Println("第二")
    defer fmt.Println("第三")

    fmt.Println("开始")
}
// 输出:开始 → 第三 → 第二 → 第一

defer 经典场景

go
// 1. 关闭文件
func readFile(path string) error {
    f, err := os.Open(path)
    if err != nil {
        return err
    }
    defer f.Close()  // 保证文件一定关闭
    // ... 使用 f ...
    return nil
}

// 2. 释放锁
mu.Lock()
defer mu.Unlock()

// 3. 记录耗时
func trackTime(name string) func() {
    start := time.Now()
    return func() {
        fmt.Printf("%s 耗时 %v\n", name, time.Since(start))
    }
}
defer trackTime("myFunc")()

panic / recover

go
// panic = 程序遇到无法继续的错误
func mustBePositive(n int) {
    if n < 0 {
        panic("n 不能为负数!")
    }
}

// recover = 捕获 panic(只在 defer 中有效)
func safeCall() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("捕获到 panic:", r)
        }
    }()
    mustBePositive(-1)  // 会 panic,但被 recover 捕获
}

⚠️ panic 应该少用。 Go 的惯例是返回 error,只在真正不可恢复的情况下用 panic(如程序初始化失败)。