错误处理
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}