英文:
Extends a Error struct, but encounter Type '*MyError' has both field and method named 'Error'
问题
我来自Java。
我正在使用一个已经在errs
包中定义了Error
的框架,我想扩展它以便可以添加更多的字段。所以我尝试使用Go的继承。
// 继承errs.Error的Error类型
type MyError struct {
errs.Error
ErrDetail string //我的错误的更多信息
st []uintptr
}
// 重写Error()方法以便消息可以更具体
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程序员来说,这非常直观。但是我得到了以下错误:
类型 '*MyError' 同时具有字段和方法名 'Error'。
这非常令人沮丧,因为Error
方法是在内置包中定义的,而Error
名称是在我的框架中定义的。有没有解决这个问题的方法?
英文:
I come from java.
And I am using a framework that already define an Error
in errs
package, I want to extend it so that I can add more fields to it. So I try using inheritance of 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())
}
This is very straightforward for a java programmer. But I get
Type '*MyError' has both field and method named 'Error'.
This is very frustrating since the method Error is define in built-in package, and the name Error
is define in my framework, is there any workaround to solve this problem?
答案1
得分: 2
你可以使用类型别名(type alias)来实现:
type SDKErr = errs.Error
// Error 继承自 errs.Error
type MyError struct {
SDKErr
ErrDetail string // 更多错误信息
st []uintptr
}
func (e *MyError) Error() string {
// ...
}
现在嵌入字段的名称是 SDKErr
,但它不会与方法名冲突,并且可以在任何需要 errs.Error
的地方使用,无需进行转换。
Playground: https://go.dev/play/p/XSWi5hzHGPh
当然,你也可以使用命名字段,而不是类型别名:
type MyError struct {
SDKErr errs.Error
ErrDetail string // 更多错误信息
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":""}
英文:
You can use a 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 {
// ...
}
Now the name of the embedded field is SDKErr
, but it won't conflict with the method name, and it can be used wherever errs.Error
is expected without the need to convert.
Playground: https://go.dev/play/p/XSWi5hzHGPh
Of course you could also use a named field, instead of an alias:
type MyError struct {
SDKErr errs.Error
ErrDetail string //more message to my error
st []uintptr
}
And then call the methods of errs.Error
simply like e.SDKErr.GetCode()
. However if MyError
is meant, for example, to be serialized to JSON, the fields of errs.Error
would appear as a nested object, whereas with the type alias they would be "flattened".
Basically if errs.Error
were defined as:
type Error struct {
Code int
}
With the type alias and embedded field, JSON would look like:
{"Code":0,"ErrDetail":""}
vs named field:
{"SDKErr":{"Code":0},"ErrDetail":""}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论