Golang中的错误比较

hec6srdp  于 12个月前  发布在  Go
关注(0)|答案(1)|浏览(86)

今天,我遇到了一个问题,当试图实现自定义错误.我的服务有2种类型的错误:常规的内部错误和处理用户相关的错误的用户错误.所以我有一些Meta数据和处理错误的函数的用户错误的结构.在这个函数中,我使用 Package 标准错误.作为函数.但它以一种奇怪的方式工作:出于某种原因,它认为常见错误也是用户错误。下面是代码片段:

package main

import (
    "errors"
    "fmt"
)

type UserError struct {
    Message string
}

func (u *UserError) Error() string {
    return u.Message
}

func As(sourceError, targetError error) bool {
    return errors.As(sourceError, &targetError)
}

func AsV2(sourceError error, targetError interface{}) bool {
    return errors.As(sourceError, &targetError)
}

func IsUserError(err error) bool {
    var userError *UserError
    return errors.As(err, &userError)
}

func main() {
    userError := errors.New("test Error")
    var emptyError *UserError

    fmt.Println(As(userError, emptyError))
    fmt.Println(AsV2(userError, emptyError))
    
    fmt.Println(IsUserError(userError))
}

字符集
在这里,我测试的功能(作为和AsV2),需要两个错误,并比较它们.第二个函数接受的目标错误,而不是错误类型的接口的唯一区别.在函数IsUserError我手动创建UserError指针,并给错误.作为函数.但在输出这个程序我得到这个:

true
true 
false


所以我的问题是,为什么前两种情况下都是错误,也就是说这是同一类型的错误,但只有在第三种情况下才能给出正确的答案?我是不是误解了Go中接口的工作原理?

6fe3ivhb

6fe3ivhb1#

在前两种情况下,它分别正确地报告错误为errorinterface{}。您添加的不必要的 Package 器函数正在创建一个间接,使其更加混乱,但如果您调用:

var emptyError *UserError
fmt.Println(errors.As(userError, emptyError))

字符集
IsUserError按照预期工作,因为它将正确的类型传递给errors.Is。我已经清理了您的代码以正确工作(Error采用非指针接收器,而不是将emptyError保留为nil),您可以在这里看到它的实际操作:https://go.dev/play/p/c5EPB5IGeD5

type UserError struct {
    Message string
}

func (u UserError) Error() string {
    return u.Message
}

func main() {
    userError := errors.New("test Error")
    var emptyError UserError

    fmt.Println(errors.As(userError, &emptyError))
}

相关问题