Errors.Is 中的 TypeOf 与 Comparable

Yap*_*axi 1 go

我正在学习 Go 中错误比较的工作原理,发现了一些我无法理解的东西。

函数errors.Is(err, target error)检查目标是否可比较。

func Is(err, target error) bool {
    if target == nil {
        return err == target
    }

    isComparable := reflectlite.TypeOf(target).Comparable()
    for {
        if isComparable && err == target {
            return true
        }
Run Code Online (Sandbox Code Playgroud)

来源

鉴于 Go 中的所有接口都是可比较的并且error都是接口,此调用处理哪种情况?

Cer*_*món 5

接口值是可比较的,但比较可能会在运行时出现混乱。规范

如果该类型的值不可比较,则比较具有相同动态类型的两个接口值会导致运行时恐慌。

当目标的具体类型不可比较时,该检查通过跳过比较来防止恐慌。

这是一个例子:

type E []byte
func (e E) Error() string { return string(e) }
func (e E) Is(target error) bool {
    t, ok := target.(E)
    return ok && bytes.Equal(e, t)
}

var a error = E{}
var b error = E{}
fmt.Println(errors.Is(a, b)) // prints true
fmt.Println(a == b)          // panics because slices are not comparable
Run Code Online (Sandbox Code Playgroud)