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

如何打印结构的 []byte 成员字符串

如何打印结构的 []byte 成员字符串

Go
潇潇雨雨 2022-05-10 13:32:41
我有以下结构:type foo struct {   number int   data []byte}我想以“漂亮”的方式从结构中打印一个对象。我做什么:obj := foo{    number: 1,    data: []byte("json"),}fmt.Printf("Obj: %+v", obj)我得到什么:Obj: {number:1 data:[106 115 111 110]}我想要的是:Obj: {number:1 data:"json"}我可以在不实现 Stringer 或使用反射的情况下做到这一点吗?
查看完整描述

2 回答

?
沧海一幻觉

TA贡献1824条经验 获得超5个赞

可能实现Stringer会更好,但这里是实现 (slightly)接口fmt的示例:Formatter


package main


import (

    "fmt"

)


type foo struct {

    number int

    data   []byte

}


func (x foo) Format(f fmt.State, c rune) {

    var s string

    switch c {

    case 's', 'v':

        if f.Flag('+') {

            s = fmt.Sprintf("{number:%d data:%q}", x.number, x.data)

        } else {

            s = fmt.Sprintf("{%d %q}", x.number, x.data)

        }

    default:

        s = "(bad formatting verb)"

    }

    f.Write([]byte(s))

}


func main() {

    o1 := foo{number: 1, data: []byte("json")}

    o2 := foo{number: 1, data: []byte("\001with\u2038unicode")}

    o3 := foo{number: 42, data: nil}

    fmt.Printf("o1: %+v\n", o1)

    fmt.Printf("o2: %v\n", o2)

    fmt.Printf("o3: %#v\n", o3)

}

对象o3在这里显示丢失了多少:处理好 nil,处理其他格式化动词和标志,等等。(我还没有谈到宽度和精度!)


查看完整回答
反对 回复 2022-05-10
?
繁花如伊

TA贡献2012条经验 获得超12个赞

(免责声明:我认为仅使用 %q 进行调试打印会更好,但这取决于您的需求。我添加此替代方法只是因为GoStringer接口是一个有趣的技巧)。


%q 之外的另一种方法是用实现 GoStringer 接口的类型包装 []byte,这将被调用格式化%#v。假设我们有:


type PrintableBuffer []byte


func (b PrintableBuffer) GoString() string {

    return string(b)

}

现在我们定义结构:


type foo struct {

    number int

    Data   PrintableBuffer

}

(要使这个技巧起作用,您需要该成员是公开的:/)


进而:


func main() {

    obj := foo{

        number: 1,

        Data:   PrintableBuffer("json"),

    }

    fmt.Printf("Obj: %#v", obj)

}

将打印出:


Obj: main.foo{number:1, Data:json}


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

添加回答

举报

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