errors包源码理解

本文详细解读了Go语言内置的errors包,包括New、Unwrap、Is、As和Join等函数的用法,以及errorString和joinError结构。重点介绍了如何处理和表示错误,以及如何正确使用ErrUnsupported变量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

本文章帮助大家对errors包的理解。


一、概述

errors是Go语言内置的标准库之一,用于处理和表示错误。

二、源码理解

package errors
import "errors"

使用errors时,需引入此包。

函数

New

func New(text string) error {
	return &errorString{text}
}

创建并返回一个错误内容为text的错误errorerrorString)。

Unwrap

func Unwrap(err error) error {
	u, ok := err.(interface {
		Unwrap() error
	})
	if !ok {
		return nil
	}
	return u.Unwrap()
}

返回err的拆包结果(error)。若err没有Unwrap() error方法,返回空。

Is

func Is(err, target error) bool { /*...*/ }

err错误树中包含匹配target错误的错误,则返回true

重点:错误树包含错误本身,然后通过Unwrap方法重复地拆包出错误,为深度优先的先序遍历。匹配是指相等或者实现了Is(error) bool方法且Is(target)返回true

注意:这里Unwrap方法可能返回error或者[]error。若返回前者,对其继续进行比较;若返回后者,遍历其元素,对它们逐个进行比较。只要出现任意一个匹配即可终止比较。

As

func As(err error, target any) bool { /*...*/ }

err错误树中包含匹配target错误的错误,将target设为该错误,返回true。类似Is方法。

重点:匹配是指错误具体值可以赋给target或者实现了As(interface{}) bool方法且As(target)返回true

注意type any = interface{}。若err非空且target不是指向实现了errorany接口的类型的非空指针,则panic

Join

func Join(errs ...error) error { /*...*/ }

将所有errs错误包装成一个错误errorjoinError)。若所有错误都是空,则返回空。

重点:非空结果实现了Unwrap() []error方法,错误内容为各错误内容的拼接,用换行符拼接。

注意:空的错误会被丢弃。

结构

errorString

type errorString struct {
	s string
}

error接口的简单实现。

errorString成员
s
s string

表示错误的内容。

errorString方法
Error
func (e *errorString) Error() string {
	return e.s
}

实现error接口。返回错误内容。

joinError

type joinError struct {
	errs []error
}

error接口的一种实现,表示由多个错误拼接的错误。

joinError成员
errs
errs []error

表示这多个错误的切片。

joinError方法
Error
func (e *joinError) Error() string {
	var b []byte
	for i, err := range e.errs {
		if i > 0 {
			b = append(b, '\n')
		}
		b = append(b, err.Error()...)
	}
	return string(b)
}

实现error接口。返回用换行符拼接的错误的内容。

Unwrap
func (e *joinError) Unwrap() []error {
	return e.errs
}

返回此错误的拆包结果([]error)。

变量

ErrUnsupported

var ErrUnsupported = New("unsupported operation")

表示操作不支持的错误。

函数、方法不应该返回此错误,而应该返回包含一个恰当上下文的错误,该上下文满足errors.Is(err, errors.ErrUnsupported),可通过直接包装ErrUnsupported,或实现Is方法来实现该错误。

errorType

var errorType = reflectlite.TypeOf((*error)(nil)).Elem()

error元素的类型。


总结

新人源码理解,望大家多多指点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ewbie

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值