我正在查看 Go“A Tour of Go”中的示例,其中我尝试了错误示例。因此,我对其进行了一些修改,并期望得到不同的结果。
package main
import (
"fmt"
"time"
)
type MyStruct struct {
When time.Time
What string
}
func (e MyStruct) Error() string {
return fmt.Sprintf("######### %v, %s", e.When, e.What)
}
func (e MyStruct) String() string {
return fmt.Sprintf("******** %v", e.When)
}
func run() MyStruct {
return MyStruct{
time.Now(),
"it didn't work",
}
}
func main() {
obj := run()
fmt.Println(obj)
}
这里我期待 main() 中的
fmt.Println(obj)
应该打印
******** 2009-11-10 23:00:00 +0000 UTC 米=+0.000000001
但是正在打印。
########## 2009-11-10 23:00:00 +0000 UTC m=+0.000000001,它不起作用
在 golang fmt.Println 中,在
Error()
方法之前考虑 Stringer
方法。当您在类型上实现了 Error
和 String
方法时,它将首先打印 Error
方法中的内容。
如fmt文档中,以
Except when printed using the verbs %T and %p
开头的部分
4. If an operand implements the error interface, the Error method will be invoked to convert the object to a string, which will then be formatted as required by the verb (if any).
5. If an operand implements method String() string, that method will be invoked to convert the object to a string, which will then be formatted as required by the verb (if any).
代码参考:handleMethods
....
case 'v', 's', 'x', 'X', 'q':
// Is it an error or Stringer?
// The duplication in the bodies is necessary:
// setting handled and deferring catchPanic
// must happen before calling the method.
switch v := p.arg.(type) {
case error:
handled = true
defer p.catchPanic(p.arg, verb, "Error")
p.fmtString(v.Error(), verb)
return
case Stringer:
handled = true
defer p.catchPanic(p.arg, verb, "String")
p.fmtString(v.String(), verb)
return
}
....