Rumah > pembangunan bahagian belakang > Golang > Bagaimanakah saya boleh mencetak struct Go dengan mudah menggunakan kaedah String() medan mereka tanpa melaksanakan String() untuk setiap struct?

Bagaimanakah saya boleh mencetak struct Go dengan mudah menggunakan kaedah String() medan mereka tanpa melaksanakan String() untuk setiap struct?

Linda Hamilton
Lepaskan: 2024-12-14 10:52:14
asal
296 orang telah melayarinya

How can I easily print Go structs using their fields' String() methods without implementing String() for every struct?

Mencetak Medan Struktur dengan String()

Kod ini:

package main

import (
    "fmt"
    "time"
)

type A struct {
    t time.Time
}

func main() {
    a := A{time.Now()}
    fmt.Println(a)
    fmt.Println(a.t)
}
````
generates this output:
Salin selepas log masuk

{{63393490800 0 0x206da0}
10-11-2009 23:00:00 0000 UTC

`A` doesn't implement `String()`, so it doesn't conform to the `fmt.Stringer` interface and presents its internal representation. Implementing `String()` for every struct can be tedious, especially upon modifications to those structs. Is there a simpler method to print structs using their fields' `String()` methods?

**The Custom Print Function**

The fmt package's behavior in this case is intrinsic and cannot be changed. However, a helper function can be crafted using reflection (provided by the `reflect` package). The function iterates through a struct's fields and invokes their `String()` methods if they exist:
Salin selepas log masuk

func PrintStruct(santara muka{}, names bool) rentetan {

v := reflect.ValueOf(s)
t := v.Type()
if t.Kind() != reflect.Struct {
    return fmt.Sprint(s)
}

var 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()
Salin selepas log masuk

}

**Integrating the Helper Function**

With the custom function in place, structs can be printed by:

```go
fmt.Println(PrintStruct(a, true))
Salin selepas log masuk

Jika mahu , kaedah String() boleh ditambah pada struct, menggunakan PrintStruct() fungsi:

func (a A) String() string {
    return PrintStruct(a, true)
}
Salin selepas log masuk

Memandangkan kami menggunakan refleksi, adalah penting untuk mengeksport medan struct untuk kebolehcapaian oleh fungsi tersuai (menambah medan tambahan untuk tujuan ujian):

type A struct {
    T          time.Time
    I          int
    unexported string
}
Salin selepas log masuk

Praktikal Contoh

Kod lengkap:

package main

import (
    "fmt"
    "reflect"
    "strings"
    "time"
)

type A struct {
    T          time.Time
    I          int
    unexported string
}

func PrintStruct(s interface{}, names bool) string {
    v := reflect.ValueOf(s)
    t := v.Type()
    if t.Kind() != reflect.Struct {
        return fmt.Sprint(s)
    }

    var 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()
}

func (a A) String() string {
    return PrintStruct(a, true)
}

func main() {
    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))
}
Salin selepas log masuk

Menguji ini kod menghasilkan:

{{63393490800 0 0x206da0}}
2009-11-10 23:00:00 +0000 UTC
{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
Salin selepas log masuk

Atas ialah kandungan terperinci Bagaimanakah saya boleh mencetak struct Go dengan mudah menggunakan kaedah String() medan mereka tanpa melaksanakan String() untuk setiap struct?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan