Z
ZHANK
函数

错误处理

error 接口、errors.New/fmt.Errorf/%w 包装、errors.Is/As

错误处理

Go 没有 try/catch——用多返回值 + error 接口。error 只是一个普通的 interface { Error() string }

学完本章你将: 掌握 error 接口、errors.New/fmt.Errorf、%w 包装、errors.Is/As。


error 基本模式

go
package main

import (
    "errors"
    "fmt"
)

func validateAge(age int) error {
    if age < 0 {
        return errors.New("年龄不能为负数")
    }
    if age > 150 {
        return fmt.Errorf("年龄 %d 不合理", age)
    }
    return nil  // 没有错误
}

func main() {
    if err := validateAge(-1); err != nil {
        fmt.Println(err)  // "年龄不能为负数"
    }
}

错误包装(Go 1.13+)

go
// %w —— 包装底层错误
func getUser(id int) error {
    _, err := db.Query("SELECT ...")
    if err != nil {
        return fmt.Errorf("查询用户 %d 失败: %w", id, err)
    }
    return nil
}

// errors.Is —— 判断是否包含某个错误
if errors.Is(err, sql.ErrNoRows) { }

// errors.As —— 提取特定类型错误
var pathErr *os.PathError
if errors.As(err, &pathErr) { }

自定义错误类型

go
type ValidationError struct {
    Field string
    Value interface{}
}

func (e *ValidationError) Error() string {
    return fmt.Sprintf("字段 %s 的值 %v 无效", e.Field, e.Value)
}

// 使用
return &ValidationError{Field: "age", Value: -1}