errors.new适用于固定无变量错误,fmt.errorf支持格式化和%w保留错误链;errors.is检查特定错误值,errors.as提取具体错误类型;自定义错误需用结构体并实现unwrap;errors.unwrap仅解一层且有panic风险。
Go 中 errors.New 和 fmt.Errorf 的适用场景区别
直接用 errors.New 创建的错误是无格式、无上下文的静态字符串;而 fmt.Errorf 支持格式化,尤其适合拼接动态信息(如 ID、状态码)。但注意:若只做简单字符串包装,fmt.Errorf("something: %w", err) 中的 %w 才能保留原始错误链,纯 %s 会切断。
常见误用:fmt.Errorf("failed to open file: %s", err) —— 这样原始错误类型和堆栈(如有)全丢了。应改用 %w 并确保传入的是 error 类型值。
-
errors.New("invalid input"):适合固定、无变量的错误(如参数校验失败) -
fmt.Errorf("timeout after %dms", timeoutMs):需要嵌入数值或字符串时用 -
fmt.Errorf("read header failed: %w", io.ErrUnexpectedEOF):需保留底层错误时必须用%w
如何正确使用 errors.Is 和 errors.As 检查错误
errors.Is 判断是否为某个**特定错误值**(比如全局变量 ErrNotFound),而 errors.As 用于提取错误链中**某个具体类型的错误实例**(比如想拿到 *os.PathError 来访问 Path 字段)。
容易踩的坑:对自定义错误类型,必须实现 Unwrap() error 方法才能被 errors.Is/errors.As 向下遍历;否则只检查最外层错误。