登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  Golang >  Go问答

Go errors.Join 传入 nil 错误后结果是什么

来源:17golang原创

时间:2026-09-15 03:12:28 320浏览 收藏

会。errors.Join 传入 nil 错误时,会把这个参数丢弃;如果所有参数都是 nil,返回值就是 nil。只要参数里还有一个非 nil 错误,返回的就是只包含这些非 nil 成员的组合错误。

官方文档:https://pkg.go.dev/errors#Join

要点速览
  • errors.Join(nil, nil) 的结果为 nil,可以直接用 err == nil 判断。
  • errors.Join(errA, nil, errB) 不会保留空成员,错误文本按非 nil 参数顺序拼接。
  • 非空组合错误实现 Unwrap() []error,应使用 errors.Iserrors.As 检查成员。

区分丢弃 nil 与全 nil

errors.Join 从 Go 1.20 开始提供,签名是 errors.Join(errs ...error) error。它先忽略输入中的 nil,再根据剩余成员决定返回值:没有剩余成员就返回 nil,有一个或多个成员就返回组合错误。

调用结果判断方式
errors.Join(nil, nil)nilerr == nil
errors.Join(errA, nil)只含 errA 的错误errors.Is(err, errA)
errors.Join(nil, errA, errB)含两个非空成员分别检查两个成员
errors.Join 的 nil 输入、非 nil 成员和组合结果静态关系框图
图1:errors.Join 的 nil 输入契约示意;nil 成员不进入组合结果,全部输入为 nil 时返回 nil。

用混合输入观察错误文本和成员

下面的例子把一个 nil 放在两个具体错误之间。重点不是打印文本,而是确认调用方看到的返回值仍能逐项判断;组合错误的文本只是各非 nil 成员的 Error() 内容按顺序、以换行连接。

package main

import (
	"errors"
	"fmt"
)

func main() {
	// nil 表示这一项没有错误,Join 会把它从成员集合中丢弃。
	err := errors.Join(errors.New("读取配置失败"), nil, errors.New("连接服务失败"))
	if err == nil {
		// 只有所有输入都为 nil 时才会进入这里。
		fmt.Println("没有错误")
		return
	}
	// 组合错误的文本按非 nil 参数的顺序连接,中间使用换行。
	fmt.Println(err)
}

因此,混合输入不会因为中间出现 nil 而整体变成 nil,也不会在错误文本中产生一行空消息。需要注意的是:只有一个非 nil 成员时,返回值仍是非 nil 的组合错误,不应据此假定它一定是原始错误的具体类型。

用 errors.Is 和 errors.As 检查成员

非 nil 的 Join 结果实现了 Unwrap() []error。调用方无需依赖标准库内部的具体类型,可以继续使用错误树上的 errors.Iserrors.As

var ErrConfig = errors.New("配置无效")

type NetworkError struct {
	// Code 让调用方可以提取结构化的网络错误信息。
	Code int
}

func (e *NetworkError) Error() string {
	// 保留稳定的错误描述,具体字段由 errors.As 读取。
	return fmt.Sprintf("网络错误(%d)", e.Code)
}

func check(err error) {
	// Is 适合判断哨兵错误是否位于组合错误的成员树中。
	if errors.Is(err, ErrConfig) {
		fmt.Println("命中配置错误")
	}
	var netErr *NetworkError
	// As 适合从成员树中提取自定义错误类型。
	if errors.As(err, &netErr) {
		fmt.Println("网络错误码:", netErr.Code)
	}
}
组合错误通过 Unwrap 列表连接 errors.Is 与 errors.As 检查成员的静态框图
图2:组合错误的检查边界示意;errors.Is 与 errors.As 通过 Unwrap() []error 访问各个非 nil 成员。

这里的 ErrConfigNetworkError 可以同时来自不同分支。errors.Is 负责匹配某个错误身份或实现的判定规则,errors.As 负责找到目标类型;两者都比断言 *errors.joinError 更稳定。

按错误数量选择返回策略

如果函数最多产生一个错误,普通的 return err 更直观;如果要并行检查多个独立任务,或者收集多个清理错误,才适合使用 errors.Join。调用方应先判断整个结果是否为 nil,再按需要用 IsAs 检查成员。

场景推荐写法原因
没有任何错误errors.Join(errs...)全 nil 自动得到 nil
单个错误并需保留原类型直接返回原错误避免无必要的组合层
多个独立错误errors.Join(errA, errB)成员可继续被 Is/As 检查

常见问题:nil 参数会制造空错误吗

errors.Join(err, nil) 会返回 nil 吗?

不会。只要至少有一个非 nil 参数,结果就是非 nil 的组合错误;nil 只是被丢弃。

errors.Join(nil, nil) 能直接返回吗?

可以,返回值为 nil。它适合把可选的多个错误统一收集后交给调用方。

能否把结果断言成具体的 join 类型?

不建议。应把返回值当作 error,使用 errors.Is、errors.As 或接口 Unwrap() []error 表达稳定的调用契约。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>