【问题标题】:Why not use %v to print int and string为什么不使用 %v 打印 int 和 string
【发布时间】:2016-12-15 08:02:18
【问题描述】:

我知道打印int 我们可以使用%d,而string 我们可以使用%s 但我们仍然可以使用%v 来打印它们。那么如果我总是使用%v 来打印它们呢?如果我这样做会出现什么问题?

【问题讨论】:

  • 我发现可以使用 %v play.golang.org/p/4HTN6U4DVU 进行递归
  • 您正在覆盖 A 的 String(),当您将 a 转换为字符串时会调用它。在 String() 中使用 %v 您试图转换 a (类型 A ),触发递归调用。切勿在该类型的 String() 中使用 %v。

标签: string go formatting printf


【解决方案1】:

不会发生任何不好的事情,但是%d 动词指示 fmt 包打印为数字(使用基数 10),%v 动词表示使用 默认值可以被覆盖的格式。

看这个例子:

type MyInt int

func (mi MyInt) String() string {
    return fmt.Sprint("*", int(mi), "*")
}

func main() {
    var mi MyInt = 2
    fmt.Printf("%d %v", mi, mi)
}

输出(在Go Playground上试试):

2 *2*

当使用%v动词时,fmt包检查值是否实现fmt.Stringer接口(这是一个单一的String() string方法),如果是,则调用该方法来转换值到string(如果指定了标志,可以进一步格式化)。

完整的格式化规则列表在fmt的包文档中,引用了相关部分:

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

  1. 如果操作数是 reflect.Value,则操作数被它所持有的具体值替换,并继续打印下一条规则。

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 2018-01-29
    • 2016-02-26
    • 1970-01-01
    • 1970-01-01
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 2012-11-11
    相关资源
    最近更新 更多