20_错误处理defer与panic
按层处理错误,正确关闭资源并理解 panic 的适用边界。
Go 基础专题 20:错误处理、defer 与 panic
学习目标:按层处理错误,正确关闭资源并理解 panic 的适用边界。
核心知识
Go 用普通返回值 error 表达预期可发生的失败。调用后先检查 err != nil,再使用结果。包装错误时用 fmt.Errorf("读取配置: %w", err) 保留原因,调用方可用 errors.Is 或 errors.As 分类。错误消息一般描述上下文,不要在每层重复打印同一错误。
package main
import (
"fmt"
"os"
)
func read(path string) ([]byte, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("读取 %s: %w", path, err)
}
return data, nil
}
func main() {
_, err := read("missing.txt")
if err != nil {
fmt.Println(err)
}
}
defer 把调用推迟到当前函数返回前,常用于 file.Close() 或解锁。多个 defer 按后进先出执行;其参数在遇到 defer 时求值。panic 表示严重且通常不可在当前层正常恢复的问题,不应用来代替普通输入错误。recover 只对同一 goroutine 的延迟函数中的 panic 有效。
关闭可写文件可能返回错误,不能总是忽略;关键持久化操作需要检查关闭或同步结果。测试时可以从错误链判断原因,而不依赖完整错误文本。
逐步理解
把错误处理分成三层:底层附加操作上下文,中间层决定是否可恢复,入口层决定怎样展示。defer 在函数返回前执行,适合关闭已成功打开的资源;打开失败时还没有可关闭对象。panic 通常意味着程序无法按当前契约继续,普通文件不存在和输入非法都应使用 error。
动手练习
练习:把解析失败包装成“读取年龄”上下文。答案要点:fmt.Errorf("读取年龄: %w", err)。