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

这段代码:


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 UTC

A没有实现String(),所以它不是 afmt.Stringer并打印其本机表示。但是为String()我想要打印的每个结构实现都非常繁琐。更糟糕的是,String()如果我添加或删除一些字段,我必须更新s。有没有更简单的方法来打印带有字段的结构String()?


白板的微信
浏览 146回答 1
1回答

宝慕林4294392

这是fmt包的实现方式,因此您无法更改。但是您可以编写一个辅助函数,它使用反射(reflect包)来遍历结构体的字段,并且可以String()在具有此类方法的字段上调用该方法。示例实现:func PrintStruct(s interface{}, names bool) string {&nbsp; &nbsp; v := reflect.ValueOf(s)&nbsp; &nbsp; t := v.Type()&nbsp; &nbsp; // To avoid panic if s is not a struct:&nbsp; &nbsp; if t.Kind() != reflect.Struct {&nbsp; &nbsp; &nbsp; &nbsp; return fmt.Sprint(s)&nbsp; &nbsp; }&nbsp; &nbsp; b := &bytes.Buffer{}&nbsp; &nbsp; b.WriteString("{")&nbsp; &nbsp; for i := 0; i < v.NumField(); i++ {&nbsp; &nbsp; &nbsp; &nbsp; if i > 0 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b.WriteString(" ")&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; v2 := v.Field(i)&nbsp; &nbsp; &nbsp; &nbsp; if names {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b.WriteString(t.Field(i).Name)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b.WriteString(":")&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if v2.CanInterface() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if st, ok := v2.Interface().(fmt.Stringer); ok {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b.WriteString(st.String())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; fmt.Fprint(b, v2)&nbsp; &nbsp; }&nbsp; &nbsp; b.WriteString("}")&nbsp; &nbsp; return b.String()}现在,当您想打印 a 时struct,您可以执行以下操作:fmt.Println(PrintStruct(a, true))您还可以选择向结构中添加一个String()方法,该方法只需调用我们的PrintStruct()函数:func (a A) String() string {&nbsp; &nbsp; return PrintStruct(a, true)}每当您更改结构时,您都不必对您的String()方法做任何事情,因为它使用反射动态遍历所有字段。笔记:由于我们使用反射,您必须导出该t time.Time字段才能工作(还添加了一些额外的字段用于测试目的):type A struct {&nbsp; &nbsp; T&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; time.Time&nbsp; &nbsp; I&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int&nbsp; &nbsp; 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
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go