Golang中自定义错误比较失败的问题

Golang中自定义错误比较失败的问题

type NotFoundError struct {
    errMessage string
}

func (n NotFoundError) Error() string {
    return n.errMessage
}

func main() {
    err := test()
    var notFound NotFoundError
    fmt.Println(errors.Is(err, notFound)) // 打印 false
    fmt.Println(err)
}

func test() error {
    err := NotFoundError{errMessage: "Not Found"}
    return err
}

大家好,fmt.Println(errors.Is(err, notFound)) 打印了 false。请帮我理解为什么会发生这种情况。


更多关于Golang中自定义错误比较失败的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

因为 NotFoundError{errMessage: "Not Found"} != NotFoundError{}

你可以改用 errors.As,这样会得到 true

package main

import (
	"errors"
	"fmt"
)

type NotFoundError struct {
	errMessage string
}

func (n NotFoundError) Error() string {
	return n.errMessage
}

func main() {
	err := test()
	var notFound NotFoundError
	fmt.Println(errors.As(err, &notFound)) // 输出 true
	fmt.Println(notFound, err) // 现在 notFound 包含了原始的 errMessage
}

func test() error {
	err := NotFoundError{errMessage: "Not Found"}
	return err
}

更多关于Golang中自定义错误比较失败的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这是因为 errors.Is 函数需要错误类型实现 Is 方法才能正确比较自定义错误。在你的代码中,NotFoundError 没有实现 Is 方法,所以 errors.Is 无法识别它们是相同的错误类型。

要解决这个问题,你需要为 NotFoundError 实现 Is 方法:

type NotFoundError struct {
    errMessage string
}

func (n NotFoundError) Error() string {
    return n.errMessage
}

func (n NotFoundError) Is(target error) bool {
    _, ok := target.(NotFoundError)
    return ok
}

func main() {
    err := test()
    var notFound NotFoundError
    fmt.Println(errors.Is(err, notFound)) // 现在打印 true
    fmt.Println(err)
}

func test() error {
    err := NotFoundError{errMessage: "Not Found"}
    return err
}

或者,如果你想要更精确的比较,可以比较错误消息:

func (n NotFoundError) Is(target error) bool {
    t, ok := target.(NotFoundError)
    if !ok {
        return false
    }
    return n.errMessage == t.errMessage
}

errors.Is 函数的工作原理是:

  1. 首先检查错误是否实现了 Is 方法
  2. 如果实现了,就调用该方法的 Is 进行判断
  3. 如果没有实现,则使用普通的相等比较

在你的原始代码中,由于没有实现 Is 方法,errors.Is 回退到使用 == 操作符比较,而 notFound 是零值,与返回的错误实例不相等,所以返回 false。

回到顶部