雖然 fmt.Println 可以方便地顯示內建類型,但其結構的行為可能冗長且缺乏資訊。考慮一個表示帶有附加欄位的時間值的結構:
type A struct { t time.Time }
使用 fmt.Println 列印此結構會導致:
{{63393490800 0 0x206da0}}
這不容易解釋。具體來說,該結構體缺少 String() 方法,這會導致其欄位無法根據需要進行格式化。
問題:
我們如何使用自訂字串列印結構體其欄位的表示形式,無需為每個欄位明確定義 String()方法struct?
解:
反射可用於迭代結構體的欄位並動態呼叫其 String() 方法。這是完成此操作的輔助函數:
func PrintStruct(s interface{}, names bool) string { v := reflect.ValueOf(s) t := v.Type() // Handle non-struct input if t.Kind() != reflect.Struct { return fmt.Sprint(s) } // Initialize buffer 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(":") } // Handle Stringer fields if v2.CanInterface() { if st, ok := v2.Interface().(fmt.Stringer); ok { b.WriteString(st.String()) continue } } // Print non-Stringer fields fmt.Fprint(b, v2) } b.WriteString("}") // Return formatted string return b.String() }
用法:
此函數可用於列印具有自定義欄位的結構體格式:
a := A{time.Now()} fmt.Println(PrintStruct(a, true)) // Display field names fmt.Println(PrintStruct(a, false)) // Omit field names
註解:
為了更方便,您可以為您的結構定義一個 String() 方法,該方法只需呼叫列印結構:
func (a A) String() string { return PrintStruct(a, true) }
以上是如何在不為每個結構明確定義 String() 方法的情況下自訂 Go 結構的列印?的詳細內容。更多資訊請關注PHP中文網其他相關文章!