it-swarm.com.de

Wie bekomme ich die json-Feldnamen einer Struktur in Golang?

Wie erhält man die Json-Feldnamen dieser Struktur?

type example struct {
    Id          int `json:"id"`
    CreatedAt   string `json:"created_at"`
    Tag         string `json:"tag"`
    Text        string `json:"text"`
    AuthorId    int `json:"author_id"`
}

Ich versuche die Felder mit dieser Funktion zu drucken:

func (b example) PrintFields() {
    val := reflect.ValueOf(b)
    for i := 0; i < val.Type().NumField(); i++ {
        fmt.Println(val.Type().Field(i).Name)
    }
}

Natürlich bekomme ich:

Id
CreatedAt
Tag
Text
AuthorId

Aber ich hätte gerne etwas wie:

id
created_at
tag
text
author_id
12
lambher

Sie verwenden den Typ StructTag , um die Tags abzurufen. Die Dokumentation, die ich verlinkt habe, hat Beispiele. Sie können nachschlagen, aber Ihr Code könnte so aussehen

func (b example) PrintFields() {
    val := reflect.ValueOf(b)
    for i := 0; i < val.Type().NumField(); i++ {
        fmt.Println(val.Type().Field(i).Tag.Get("json"))
    }
}

NOTE Das json-Tag-Format unterstützt mehr als nur Feldnamen wie omitempty oder string. Wenn Sie also einen Ansatz benötigen, der dies berücksichtigt, sollten Sie die PrintFields-Funktion weiter verbessern:

  1. wir müssen prüfen, ob das json-Tag - ist (d. h. json:"-").
  2. wir müssen prüfen, ob der Name existiert, und ihn isolieren

Etwas wie das:

func (b example) PrintFields() {
    val := reflect.ValueOf(b)
    for i := 0; i < val.Type().NumField(); i++ {
        t := val.Type().Field(i)
        fieldName := t.Name

        if jsonTag := t.Tag.Get("json"); jsonTag != "" && jsonTag != "-" {
            if commaIdx := strings.Index(jsonTag, ","); commaIdx > 0 {
                fieldName = jsonTag[:commaIdx]
            }
        }


        fmt.Println(fieldName)
    }
}
14
ain

Anstatt StructFields Name zu verwenden, können Sie Tag verwenden, um ein StructTag-Objekt zu erhalten ..__ Siehe: https://golang.org/pkg/reflect/#StructTag

Dann können Sie die StructTag- oder Get-Methoden der Lookup-Methode verwenden, um das json-Tag abzurufen:

Get verwenden:

func (b example) PrintFields() {
    val := reflect.ValueOf(b)
    for i := 0; i < val.Type().NumField(); i++ {
        // prints empty line if there is no json tag for the field
        fmt.Println(val.Type().Field(i).Tag.Get("json"))
    }
}

Lookup verwenden:

func (b example) PrintFields() {
    val := reflect.ValueOf(b)
    for i := 0; i < val.Type().NumField(); i++ {
        // skips fields without json tag
        if tag, ok := val.Type().Field(i).Tag.Lookup("json"); ok {
            fmt.Println(tag)
        }
    }
}
4
jussius

Benutzen:

func (b example) PrintFields() {
    val := reflect.ValueOf(b)
    t := val.Type()
    for i := 0; i < t.NumField(); i++ {
        fmt.Println(t.Field(i).Tag.Get("json"))
    }
}

Sehen Sie es auf Spielplatz.

2
sadlil

Nicht der Name, nach dem Sie suchen. Was Sie suchen, ist der Tag

func (b example) PrintFields() {
    val := reflect.ValueOf(b)
    for i := 0; i < val.Type().NumField(); i++ {
        fmt.Println(val.Type().Field(i).Tag.Get("json"))
    }
}
1
Wendy Adi

eine aktualisierte Version mit einer generischen Schnittstelle als Parameter:

func PrintFields(b interface{}) {
    val := reflect.ValueOf(b)
    for i := 0; i < val.Type().NumField(); i++ {
        t := val.Type().Field(i)
        fieldName := t.Name

        if jsonTag := t.Tag.Get("json"); jsonTag != "" && jsonTag != "-" {
            // check for possible comma as in "...,omitempty"
            var commaIdx int
            if commaIdx = strings.Index(jsonTag, ","); commaIdx < 0 {
                commaIdx = len(jsonTag)
            }
            fieldName = jsonTag[:commaIdx]
        }
        fmt.Println(fieldName)
    }
}
0
ChuckM