今天,我遇到了一个问题,当试图实现自定义错误.我的服务有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中接口的工作原理?
1条答案
按热度按时间6fe3ivhb1#
在前两种情况下,它分别正确地报告错误为
error
和interface{}
。您添加的不必要的 Package 器函数正在创建一个间接,使其更加混乱,但如果您调用:字符集
IsUserError
按照预期工作,因为它将正确的类型传递给errors.Is
。我已经清理了您的代码以正确工作(Error
采用非指针接收器,而不是将emptyError
保留为nil
),您可以在这里看到它的实际操作:https://go.dev/play/p/c5EPB5IGeD5型