Heim > Backend-Entwicklung > Golang > Wie kann ich Go-Strukturen einfach mit den String()-Methoden ihrer Felder drucken, ohne String() für jede Struktur zu implementieren?

Wie kann ich Go-Strukturen einfach mit den String()-Methoden ihrer Felder drucken, ohne String() für jede Struktur zu implementieren?

Linda Hamilton
Freigeben: 2024-12-14 10:52:14
Original
295 Leute haben es durchsucht

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

Strukturfelder mit String() drucken

Dieser Code:

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:
Nach dem Login kopieren

{{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:
Nach dem Login kopieren

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()
Nach dem Login kopieren

}

**Integrating the Helper Function**

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

```go
fmt.Println(PrintStruct(a, true))
Nach dem Login kopieren

Falls gewünscht , kann einer Struktur eine String()-Methode hinzugefügt werden, die PrintStruct() aufruft Funktion:

func (a A) String() string {
    return PrintStruct(a, true)
}
Nach dem Login kopieren

Da wir Reflektion verwenden, ist es wichtig, Strukturfelder für den Zugriff durch die benutzerdefinierte Funktion zu exportieren (zusätzliche Felder zu Testzwecken hinzugefügt):

type A struct {
    T          time.Time
    I          int
    unexported string
}
Nach dem Login kopieren

Praktisch Beispiel

Der vollständige Code:

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))
}
Nach dem Login kopieren

Testen dieses Codes produziert:

{{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
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonWie kann ich Go-Strukturen einfach mit den String()-Methoden ihrer Felder drucken, ohne String() für jede Struktur zu implementieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage