为了账号安全,请及时绑定邮箱和手机立即绑定

为什么 Error() 优先于 String()

为什么 Error() 优先于 String()

Go
慕尼黑8549860 2021-10-04 17:13:07
我一直在浏览巡回演出,但我无法弄清楚为什么会发生这种情况。当您有Stringer( String() string) 时,fmt将使用该方法打印到控制台。就像在https://tour.golang.org/methods/6 中建议的那样但是,如果您添加Error() string,则会调用此方法而不是String() string。package mainimport "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)}结果:失败 失败我不明白为什么fmt.Println使用Error而不是String.
查看完整描述

2 回答

?
30秒到达战场

TA贡献1828条经验 获得超6个赞

仅仅因为这就是它的实现方式。Anerror在实践中更重要,所以如果error实现了接口,就会打印出来。

这是记录在案的,请阅读以下软件包文档fmt

除了使用动词 %T 和 %p 打印时,特殊格式注意事项适用于实现某些接口的操作数。按申请顺序:

  1. 如果一个操作数实现了 Formatter 接口,它将被调用。Formatter 提供对格式的精细控制。

  2. 如果 %v 动词与 # 标志 (%#v) 一起使用并且操作数实现了 GoStringer 接口,则将调用该接口。

如果格式(对于 Println 等隐式为 %v)对字符串有效(%s %q %v %x %X),则以下两条规则适用:

  1. 如果操作数实现了错误接口,则将调用 Error 方法将对象转换为字符串,然后根据动词(如果有)的要求对其进行格式化。

  2. 如果操作数实现方法String() string,则将调用该方法以将对象转换为字符串,然后将根据动词(如果有)的要求对其进行格式化。

所以error是3就行了,而String()只有4


查看完整回答
反对 回复 2021-10-04
?
侃侃无极

TA贡献2051条经验 获得超10个赞

原因很简单:当fmt使用它的任何打印函数时,它会为每个参数做一个类型切换来确定它应该如何打印,并且在那个类型切换case error出现在case Stringer.


查看完整回答
反对 回复 2021-10-04
  • 2 回答
  • 0 关注
  • 212 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信