185 votes

Parcourir les champs d'une structure en Go

Fondamentalement, la seule façon (que je connais) d'itérer à travers les valeurs des champs d'une struct est comme suit :

type Example struct {
    a_number uint32
    a_string string
}

//...

r := &Example{(2 << 31) - 1, "...."}:
for _, d:= range []interface{}{ r.a_number, r.a_string, } {
  //faire quelque chose avec le d
}

Je me demandais s'il y avait une meilleure et plus polyvalente façon d'obtenir []interface{}{ r.a_number, r.a_string, }, pour ne pas avoir à lister chaque paramètre individuellement, ou bien, s'il y avait une meilleure façon de boucler à travers une struct ?

J'ai essayé de parcourir le reflect package, mais j'ai rencontré un obstacle, car je ne sais pas quoi faire une fois que j'ai obtenu reflect.ValueOf(*r).Field(0).

Merci !

-1voto

STEEL Points 649

En utilisant la solution de Chetan Kumar et au cas où vous auriez besoin de l'appliquer à une map[string]int

package main

import (
    "fmt"
    "reflect"
)

type BaseStats struct {
    Hp           int
    HpMax        int
    Mp           int
    MpMax        int
    Strength     int
    Speed        int
    Intelligence int
}

type Stats struct {
    Base map[string]int
    Modifiers []string
}

func StatsCreate(stats BaseStats) Stats {
    s := Stats{
        Base: make(map[string]int),
    }

    //Itérer à travers les champs d'une structure
    v := reflect.ValueOf(stats)
    typeOfS := v.Type()

    for i := 0; i< v.NumField(); i++ {
        val := v.Field(i).Interface().(int)
        s.Base[typeOfS.Field(i).Name] = val
    }
    return s
}

func (s Stats) GetBaseStat(id string) int {
    return s.Base[id]
}

func main() {
    m := StatsCreate(BaseStats{300, 300, 300, 300, 10, 10, 10})

    fmt.Println(m.GetBaseStat("Hp"))
}

-1voto

jamesev15 Points 1

Utilisez le package reflect. Tout d'abord, obtenez le type de la variable avec reflect.TypeOf et obtenez le nombre d'éléments avec reflect.NumField. Pour obtenir les valeurs des champs de manière itérative d'une structure, vous devez réfléchir sur la variable et utiliser la fonction rg.Elem().Field(i)

package main

import (
    "fmt"
    "reflect"
)

type Gopher struct {
    Name  string
    Color string
    Year  int
}

func main() {
    g := Gopher{Name: "AAA", Color: "BBBB", Year: 2021}

    gtype := reflect.TypeOf(g)

    numFields := gtype.NumField()

    rg := reflect.ValueOf(&g)

    for i := 0; i < numFields; i++ {
        fmt.Println(rg.Elem().Field(i))
    }
}

-2voto

Ilya Points 1

En Go, vous pouvez utiliser le package reflect pour itérer à travers les champs d'une structure. Le package reflect vous permet d'inspecter les propriétés des valeurs à l'exécution, y compris leur type et leur valeur. Voici un exemple de comment itérer à travers les champs d'une structure :

Go Playground

package main

import (
    "fmt"
    "reflect"
)

type Movie struct {
    Name string
    Year int
}

func main() {
    p := Movie{"The Dark Knight", 2008}

    val := reflect.ValueOf(p)
    typ := val.Type()

    for i := 0; i < val.NumField(); i++ {
        field := val.Field(i)
        fieldType := typ.Field(i)

        fmt.Printf("Nom du champ : %s, Valeur du champ : %v\n", fieldType.Name, field.Interface())
    }
}

Sortie :

Nom du champ : Name, Valeur du champ : The Dark Knight
Nom du champ : Age, Valeur du champ : 2008

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X