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

如何使用字段的 String() 打印结构?

如何使用字段的 String() 打印结构?

Go
白板的微信 2021-11-15 16:40:34
这段代码:type A struct {    t time.Time}func main() {    a := A{time.Now()}    fmt.Println(a)    fmt.Println(a.t)}印刷:{{63393490800 0 0x206da0}}2009-11-10 23:00:00 +0000 UTCA没有实现String(),所以它不是 afmt.Stringer并打印其本机表示。但是为String()我想要打印的每个结构实现都非常繁琐。更糟糕的是,String()如果我添加或删除一些字段,我必须更新s。有没有更简单的方法来打印带有字段的结构String()?
查看完整描述

1 回答

?
宝慕林4294392

TA贡献2021条经验 获得超8个赞

这是fmt包的实现方式,因此您无法更改。


但是您可以编写一个辅助函数,它使用反射(reflect包)来遍历结构体的字段,并且可以String()在具有此类方法的字段上调用该方法。


示例实现:


func PrintStruct(s interface{}, names bool) string {

    v := reflect.ValueOf(s)

    t := v.Type()

    // To avoid panic if s is not a struct:

    if t.Kind() != reflect.Struct {

        return fmt.Sprint(s)

    }


    b := &bytes.Buffer{}

    b.WriteString("{")

    for i := 0; i < v.NumField(); i++ {

        if i > 0 {

            b.WriteString(" ")

        }

        v2 := v.Field(i)

        if names {

            b.WriteString(t.Field(i).Name)

            b.WriteString(":")

        }

        if v2.CanInterface() {

            if st, ok := v2.Interface().(fmt.Stringer); ok {

                b.WriteString(st.String())

                continue

            }

        }

        fmt.Fprint(b, v2)

    }

    b.WriteString("}")

    return b.String()

}

现在,当您想打印 a 时struct,您可以执行以下操作:


fmt.Println(PrintStruct(a, true))

您还可以选择向结构中添加一个String()方法,该方法只需调用我们的PrintStruct()函数:


func (a A) String() string {

    return PrintStruct(a, true)

}

每当您更改结构时,您都不必对您的String()方法做任何事情,因为它使用反射动态遍历所有字段。


笔记:


由于我们使用反射,您必须导出该t time.Time字段才能工作(还添加了一些额外的字段用于测试目的):


type A struct {

    T          time.Time

    I          int

    unexported string

}

测试它:


a := A{time.Now(), 2, "hi!"}

fmt.Println(a)

fmt.Println(PrintStruct(a, true))

fmt.Println(PrintStruct(a, false))

fmt.Println(PrintStruct("I'm not a struct", true))

输出(在Go Playground上试试):


{T:2009-11-10 23:00:00 +0000 UTC I:2 unexported:hi!}

{T:2009-11-10 23:00:00 +0000 UTC I:2 unexported:hi!}

{2009-11-10 23:00:00 +0000 UTC 2 hi!}

I'm not a struct


查看完整回答
反对 回复 2021-11-15
  • 1 回答
  • 0 关注
  • 145 浏览
慕课专栏
更多

添加回答

举报

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