我一直在浏览巡演,我无法弄清楚为什么会这样.
当你有一个Stringer
(String() string
)时,fmt
将使用该方法打印到控制台.如https://tour.golang.org/methods/6中所述
但是,如果添加Error() string
,则调用此方法而不是String() string
.
package main
import "fmt"
type Person struct {
Name string
Age int
}
func (p *Person) String() string {
return fmt.Sprintf("%v (%v years)", p.Name, p.Age)
}
func (p *Person) Error() string {
return fmt.Sprintf("Failed")
}
func main() {
a := &Person{"Arthur Dent", 42}
z := &Person{"Zaphod Beeblebrox", 9001}
fmt.Println(a, z)
}
Run Code Online (Sandbox Code Playgroud)
结果:
失败失败
我不明白为什么fmt.Println
用Error
而不是String
.
仅仅因为这是它的实现方式.一个error
是在实践中更重要,所以如果error
接口被实现,那将被打印出来.
这是记录在案的,阅读包文档fmt
:
除非使用动词%T和%p打印,否则特殊格式注意事项适用于实现某些接口的操作数.按申请顺序:
如果操作数实现Formatter接口,则将调用它.Formatter提供格式化的精细控制.
如果%v动词与#flag(%#v)一起使用,并且操作数实现了GoStringer接口,则将调用该接口.
如果格式(对于Println等隐式%v)对字符串有效(%s%q%v%x%X),则适用以下两个规则:
如果操作数实现了错误接口,则将调用Error方法将对象转换为字符串,然后根据动词的需要对其进行格式化(如果有).
如果操作数实现方法String()字符串,则将调用该方法将对象转换为字符串,然后根据动词(如果有)格式化该字符串.
所以error
是3 次就行了,而String()
只有4 次.