首頁 > 後端開發 > Golang > 如何在不為每個結構明確定義 String() 方法的情況下自訂 Go 結構的列印?

如何在不為每個結構明確定義 String() 方法的情況下自訂 Go 結構的列印?

Barbara Streisand
發布: 2024-12-08 16:49:11
原創
259 人瀏覽過

How to Customize the Printing of Go Structs Without Explicitly Defining a String() Method for Each Struct?

使用自訂欄位格式列印結構

雖然 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
登入後複製

註解:

  • PrintStruct函數假定導出的結構欄位。
  • 為了更方便,您可以為您的結構定義一個 String() 方法,該方法只需呼叫列印結構:

    func (a A) String() string {
      return PrintStruct(a, true)
    }
    登入後複製

以上是如何在不為每個結構明確定義 String() 方法的情況下自訂 Go 結構的列印?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板