Fondamentalement, le seul moyen (que je sache) de parcourir les valeurs des champs d'un 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, } {
//do something with the d
}
Je me demandais s'il existait un moyen plus performant et plus polyvalent de réaliser []interface{}{ r.a_number, r.a_string, }
. Je n'ai donc pas besoin de répertorier chaque paramètre individuellement. Sinon, existe-t-il un meilleur moyen de parcourir une structure?
J'ai essayé de regarder à travers le paquet reflect
, mais je me suis heurté à un mur, car je ne sais pas quoi faire une fois que j'ai récupéré reflect.ValueOf(*r).Field(0)
.
Merci!
Une fois que vous avez récupéré le reflect.Value
Du champ en utilisant Field(i)
, vous pouvez en obtenir une valeur d'interface en appelant Interface()
. Ladite valeur d'interface représente alors la valeur du champ.
Il n’existe aucune fonction permettant de convertir la valeur du champ en un type concret, car, comme vous le savez peut-être, aucun médicament générique n’est utilisé. Ainsi, il n'y a pas de fonction avec la signature GetValue() T
avec T
étant le type de ce champ (qui change bien sûr, en fonction du champ).
Le plus proche que vous puissiez obtenir au rendez-vous est GetValue() interface{}
et c’est exactement ce que propose reflect.Value.Interface()
.
Le code suivant montre comment obtenir les valeurs de chaque champ exporté dans une structure en utilisant une réflexion ( play ):
import (
"fmt"
"reflect"
)
func main() {
x := struct{Foo string; Bar int }{"foo", 2}
v := reflect.ValueOf(x)
values := make([]interface{}, v.NumField())
for i := 0; i < v.NumField(); i++ {
values[i] = v.Field(i).Interface()
}
fmt.Println(values)
}
Si vous voulez parcourir les champs et les valeurs d'une structure, vous pouvez utiliser le code Go ci-dessous comme référence.
package main
import (
"fmt"
"reflect"
)
type Student struct {
Fname string
Lname string
City string
Mobile int64
}
func main() {
s := Student{"Chetan", "Kumar", "Bangalore", 7777777777}
v := reflect.ValueOf(s)
typeOfS := v.Type()
for i := 0; i< v.NumField(); i++ {
fmt.Printf("Field: %s\tValue: %v\n", typeOfS.Field(i).Name, v.Field(i).Interface())
}
}
Run in playground
Remarque: Si les champs de votre structure ne sont pas exportés, la v.Field(i).Interface()
donnera la panique panic: reflect.Value.Interface: cannot return value obtained from unexported field or method.