String 如何使用字段的字符串()打印结构?
此代码:String 如何使用字段的字符串()打印结构?,string,go,struct,String,Go,Struct,此代码: 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(),因此它不是fmt.Stringer,并打印其本机表示形式。但是,为我要打印的每个结构实现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()
,因此它不是fmt.Stringer
,并打印其本机表示形式。但是,为我要打印的每个结构实现String()
非常繁琐。更糟糕的是,如果添加或删除某些字段,我必须更新String()
s。是否有一种更简单的方法来打印结构,以及它的字段“String()
s?”这就是fmt
包的实现方式,因此您不能更改它
但是您可以编写一个helper函数,该函数使用反射(包)在结构的字段上迭代,并且可以在字段上调用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()
}
您还可以选择将String()
方法添加到您的结构中,该方法只需调用我们的PrintStruct()
函数:
func (a A) String() string {
return PrintStruct(a, true)
}
无论何时更改结构,都不必使用String()
方法,因为它使用反射动态遍历所有字段
注意事项:
由于我们使用的是反射,您必须导出t time.time
字段才能使其工作(还添加了一些额外字段用于测试):
测试它:
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))
输出(在上尝试):
这正是我试图避免的。我想使用
time.time
的String()
,而不是公开其内部实现。
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))
{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