扩展错误结构,但遇到类型“*MyError”同时具有名为 'Error' 的字段和方法

Extends a Error struct, but encounter Type '*MyError' has both field and method named 'Error'

我来自java.

并且我使用的框架已经在 errs 包中定义了一个 Error,我想扩展它以便我可以向它添加更多字段。所以我尝试使用go的继承。

// Error to inherit from errs.Error
type MyError struct {
    errs.Error
    ErrDetail string    //more message to my error
    st        []uintptr 
}

// override Error() so that the message can be more specific
func (e *MyError) Error() string {
    if e == nil {
        return ErrorCodeSuccess.ErrDetail
    }
    return fmt.Sprintf("Code:%d, ErrDetail:%s, Msg:%s", e.GetCode(), e.GetErrDetail(), e.GetMsg())
} 

这对于 java 程序员来说非常简单。但是我得到

 Type '*MyError' has both field and method named 'Error'.

这很令人沮丧,因为方法 Error 是在内置包中定义的,而名称 Error 是在我的框架中定义的,有什么解决方法可以解决这个问题吗?

您可以使用 type alias:

type SDKErr = errs.Error

// Error to inherit from errs.Error
type MyError struct {
    SDKErr
    ErrDetail string    //more message to my error
    st        []uintptr 
}

func (e *MyError) Error() string {
    // ...
} 

现在内嵌字段的名字是SDKErr,但是不会和方法名冲突,不需要转换就可以在需要errs.Error的地方使用。

游乐场:https://go.dev/play/p/XSWi5hzHGPh

当然你也可以使用命名字段,而不是别名:

type MyError struct {
    SDKErr errs.Error
    ErrDetail string    //more message to my error
    st        []uintptr 
}

然后像e.SDKErr.GetCode()一样调用errs.Error的方法。但是,如果 MyError 意味着要序列化为 JSON,errs.Error 的字段将显示为嵌套对象,而使用类型别名它们将被“扁平化”。

基本上如果 errs.Error 被定义为:

type Error struct {
    Code int
}

使用类型别名和嵌入字段,JSON 看起来像:

{"Code":0,"ErrDetail":""}

对比命名字段:

{"SDKErr":{"Code":0},"ErrDetail":""}