Golang无法模仿error接口问题:Error()方法为何无需显式调用
问题原因解答
两个代码段输出差异的核心原因
这一差异是Go标准库fmt包的内置打印规则导致的:
- Go内置了
error标准接口,定义为:type error interface { Error() string }fmt包在打印任意值时,会优先判断该值是否实现了error接口,如果实现了,就会自动调用其Error()方法,用返回的字符串作为打印内容。
你的第一段代码中,*argError实现了Error()方法,满足error接口要求,你在f2中返回的是error类型的结果,所以fmt.Println(b)时自动调用了Error()方法,输出了你写的带----的内容。 - 第二段代码中你自定义的
myerr接口和Apple()方法是你自己定义的非标准接口,fmt包没有内置对这个接口的特殊处理逻辑。当你打印j时,fmt包找不到Error()或者String()(fmt.Stringer接口的方法,也是fmt包内置识别的)方法,就会按接口指向的结构体指针的默认格式输出,不会调用Apple()方法,自然不会出现带---的内容。
如果你想让第二段代码也能自动打印Apple()的返回结果,只需要让*dummy实现fmt.Stringer接口即可,新增代码如下:
func (d *dummy) String() string { return d.Apple() }
Error()方法不需要显式调用的原因
这是fmt包的内置处理逻辑,不需要上层开发者手动调用:fmt系列打印函数在处理输入参数时,会通过类型断言判断参数是否实现了error接口,如果匹配就会主动调用Error()方法获取字符串用于输出,这是Go标准库为了简化错误打印做的设计。
格式化后的参考代码
第一段代码
package main import ( "fmt" ) type argError struct { arg int prob string } func (e *argError) Error() string { return fmt.Sprintf("%d ---- %s", e.arg, e.prob) } func f2(arg int) (int, error) { return -1, &argError{arg, "can't work with it"} } func main() { a,b := f2(42) fmt.Println(a) fmt.Println(b) }
第二段代码
package main import ( "fmt" ) type myerr interface { Apple() string } type dummy struct { age int name string } func (d *dummy) Apple() string { return fmt.Sprintf("%d --- %s", d.age, d.name) } func f1(arg int) (string, myerr) { return "f1", &dummy{arg, "ret"} } func main() { i, j := f1(42) fmt.Println(i) fmt.Println(j) }
内容的提问来源于stack exchange,提问作者mithun s
相关产品推荐
相关产品推荐

