GoLang错误/接口机制
首先,我不太确定这个问题是与错误有关,还是与GoLang中的接口有关 我正在按照教程学习GoLang。本教程附带了这个问题 这是错误接口的基本演示。当我像这样修改代码时,我感到困惑:GoLang错误/接口机制,go,Go,首先,我不太确定这个问题是与错误有关,还是与GoLang中的接口有关 我正在按照教程学习GoLang。本教程附带了这个问题 这是错误接口的基本演示。当我像这样修改代码时,我感到困惑: package main import ( "fmt" "time" ) type MyError struct { When time.Time What string } func (e *MyError) Error() string { return fmt.S
package main
import (
"fmt"
"time"
)
type MyError struct {
When time.Time
What string
}
func (e *MyError) Error() string {
return fmt.Sprintf ("at %v, %s", e.When, e.What)
}
func run() *MyError {
return &MyError{
time.Now(), "it didn't work",
}
}
func main() {
if err := run(); err != nil {
fmt.Println(err)
}
err1 := MyError{time.Now(), "it works again"}
fmt.Println(err1)
fmt.Println(err1.Error())
}
这段代码的输出是:
at 2015-04-06 15:00:07.1541719 +0800 CST, it didn't work
{2015-04-06 15:00:07.155172 +0800 CST it works again}
at 2015-04-06 15:00:07.155172 +0800 CST, it works again
让我困惑的是fmt将在什么条件下隐式调用MyError.Error()接口
据我所知,第一个和第二个fmt.Println()应该具有相同的变量类型:MyError。但是很明显,第一个调用涉及MyError类型的Error()的隐式调用,而第二个调用则没有
是什么机制造成了这种差异
感谢您研究这个初学者的问题
fmt.Println
使用反射首先检查变量的类型,如果类型实现了Stringer
接口,则调用String
方法。其次,如果类型实现了Error
接口,它将调用Error
方法。您的代码将Error()实现绑定到指针*MyError
在代码中,您传递的是类型(确切地说是其副本),而不是指针
如果你改变
err1 := MyError{time.Now(), "it works again"}
到
它会像你期望的那样工作。谢谢!我做了测试,是的。谢谢你的解释!还有一个问题,对于struct类型,GoLang有stringer的默认实现,如果我们实现一个错误接口,会不会混淆fmt.Println,不知道使用哪个接口?实际上是相反的
Error()string
在@DaveC之前使用(优先于)string()Error
,这很有趣,对吗?如果您同时定义了Error()string
,那么定义string()string
就没有用了,至少不能在指向类型结构的指针上。。。
err1 := &MyError{time.Now(), "it works again"}