Je souhaite créer une méthode qui prend une structure comme interface{}
et renvoie true
si l'un des champs de la structure fournie est nul.Marche récursive dans les structures imbriquées
Voici ce que j'ai en ce moment:
// ContainsNil returns true if any fields within the supplied structure are nil.
//
// If the supplied object is not a struct, the method will panic.
// Nested structs are inspected recursively.
// Maps and slices are not inspected deeply. This may change.
func ContainsNil(obj interface{}) bool {
if obj == nil {
return true
}
s := reflect.Indirect(reflect.ValueOf(obj))
for i := 0; i < s.NumField(); i++ {
f := s.Type().Field(i)
field := s.Field(i)
if fieldIsExported(f) { // Exported-check must be evaluated first to avoid panic.
if field.Kind() == reflect.Struct {
if ContainsNil(field.Addr()) {
return true
}
} else {
if field.IsNil() {
return true
}
if field.Interface() == nil {
return true
}
}
}
}
return false
}
func fieldIsExported(field reflect.StructField) bool {
log.Println(field.Name)
return field.Name[0] >= 65 == true && field.Name[0] <= 90 == true
}
Et un test défaillant:
func Test_ContainsNil_NilNestedValue_ReturnsTrue(t *testing.T) {
someNestedStruct := &c.SomeNestedStruct{
SomeStruct: c.SomeStruct{
SomeString: nil,
},
}
result := util.ContainsNil(someNestedStruct)
assert.True(t, result)
}
Le code de test exécute sans paniquer, mais échoue parce que la méthode renvoie false
plutôt que true
. Le problème que j'ai est que je ne peux pas comprendre comment passer correctement la structure imbriquée dans l'appel récursif à ContainsNil
.
Lorsque l'appel récursif est effectué pour la structure imbriquée, la méthode fieldIsExported
renvoie false
car elle ne reçoit pas la valeur attendue.
Je m'attends à ce que fieldIsExported
reçoive "SomeStruct" lors de son premier appel et reçoive "SomeString" lors du second appel (récursif). Le premier appel se passe comme prévu, mais sur le deuxième appel, fieldIsExported
reçoit "typ", quand je m'attends à recevoir "SomeString".
J'ai fait beaucoup de recherches sur l'utilisation de la réflexion sur les structures, mais je n'ai pas encore réussi à comprendre. Des idées?
Références:
- Pass by reference nested structures through reflection
- golang - reflection on embedded structs
- https://golang.org/pkg/reflect/
- Lot de googler
Cela prend tout son sens. Merci beaucoup pour l'aide! – Joe