【问题标题】:Different behavior when printing a bytes.Buffer in Go在 Go 中打印 bytes.Buffer 时的不同行为
【发布时间】:2019-03-31 00:55:43
【问题描述】:

当我执行这个时:

buf := new(bytes.Buffer)
buf.WriteString("Hello world")
fmt.Println(buf)

它打印Hello World

但是如果我执行这个:

var buf bytes.Buffer
buf.WriteString("Hello world")
fmt.Println(buf)

打印:{[72 101 108 108 111 32 119 111 114 108 100] 0 [72 101 108 108 111 32 119 111 114 108 100 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 0}

我知道这是byte.Buffer结构的内容,但为什么打印成不同的格式?

【问题讨论】:

  • 它当前打印您在 Buffer 切片中给出的 ASCII 字符的十进制表示。请参阅String()bytes.Buffer

标签: string pointers go struct


【解决方案1】:

因为*bytes.Buffer 类型的值有一个String() 方法(*bytes.Buffermethod set 包含String() 方法),而bytes.Buffer 类型的值没有。

fmt 包检查正在打印的值是否具有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() 字符串,将调用该方法将对象转换为字符串,然后根据动词(如果有)的要求对其进行格式化。

Buffer.String() 方法将其内容作为string 返回,这就是您在传递*bytes.Buffer 类型的指针时看到的打印内容。当您传递bytes.Buffer 类型的非指针值时,它会像普通结构值一样简单地打印,其默认格式为:

{field0 field1 ...}

查看相关/类似问题:

The difference between t and *t

Why not use %v to print int and string

Why does Error() have priority over String()

【讨论】:

    猜你喜欢
    • 2013-11-07
    • 1970-01-01
    • 1970-01-01
    • 2021-11-17
    • 2021-06-27
    • 1970-01-01
    • 2015-02-13
    • 2014-02-14
    • 1970-01-01
    相关资源
    最近更新 更多