【问题标题】:Why does Error() have priority over String()为什么 Error() 优先于 String()
【发布时间】:2015-05-11 05:05:05
【问题描述】:

我一直在寻找 go 的导览,但我无法弄清楚为什么会发生这种情况。

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

【问题讨论】:

    标签: string go


    【解决方案1】:

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

    这是有文档的,请阅读fmt的包文档:

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

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

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

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

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

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

    所以error 在列表中排名第三,而String() 仅排名第四

    【讨论】:

      【解决方案2】:

      原因很简单:当 fmt 使用它的任何打印函数时,它会为每个参数进行类型切换以确定应该如何打印,并且在该类型切换中 case error 出现在case Stringer 之前。

      【讨论】:

        猜你喜欢
        • 2011-12-13
        • 1970-01-01
        • 2016-04-17
        • 2014-01-12
        • 2022-11-30
        • 1970-01-01
        • 2014-01-17
        • 2012-12-29
        相关资源
        最近更新 更多