猿问

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

我一直在浏览巡回演出,但我无法弄清楚为什么会发生这种情况。


当您有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)

}

结果:


失败 失败


我不明白为什么fmt.Println使用Error而不是String.


慕尼黑8549860
浏览 213回答 2
2回答

30秒到达战场

仅仅因为这就是它的实现方式。Anerror在实践中更重要,所以如果error实现了接口,就会打印出来。这是记录在案的,请阅读以下软件包文档fmt:除了使用动词 %T 和 %p 打印时,特殊格式注意事项适用于实现某些接口的操作数。按申请顺序:如果一个操作数实现了 Formatter 接口,它将被调用。Formatter 提供对格式的精细控制。如果 %v 动词与 # 标志 (%#v) 一起使用并且操作数实现了 GoStringer 接口,则将调用该接口。如果格式(对于 Println 等隐式为 %v)对字符串有效(%s %q %v %x %X),则以下两条规则适用:如果操作数实现了错误接口,则将调用 Error 方法将对象转换为字符串,然后根据动词(如果有)的要求对其进行格式化。如果操作数实现方法String() string,则将调用该方法以将对象转换为字符串,然后将根据动词(如果有)的要求对其进行格式化。所以error是3次就行了,而String()只有4次。

侃侃无极

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

相关分类

Go
我要回答