2017-09-14 4 views
-1

J'ai un type spécial dans Golang ce qui représente une chaîne avec la méthode Validate.La méthode d'appel appartient au domaine de la struct

type string128 string 

func (s *string128) Validate() error { 
    ... 
    return nil 
} 

Il y a struct ont des champs comme les suivants:

type Strings1 struct { 
    str1 string 
    str2 string128 
    str3 string128 
    ... 
    strN+1 string128 
    strN+2 string 
} 

type Strings2 struct { 
    str1 string 
    str2 string128 
    str3 string128 
    ... 
    strN+1 string128 
    strN+2 string 
} 

Je veux faire une fonction où je peux les passer et si le champ ont une fonction Valider() appeler.

Qu'est-ce que je l'ai fait:

func validateStruct(a interface{}) error { 
    v := reflect.ValueOf(a) 
    t := reflect.TypeOf(a) 
    for i := 0; i < v.NumField(); i++ { 
     err := reflect.TypeOf(v.Field(i).Interface()).MethodByName("Validate").Call(...) 
    } 
    return nil 
} 

Mais il est faire un bon nombre de panique.

Répondre

0

J'ai trouvé le problème. Le reflect.TypeOf(v.Field(i).Interface()).MethodByName("Validate") ne voit la fonction que si la fonction de validation n'a pas de récepteur de pointeur, donc si je modifie la fonction de validation de la chaîne128 à func (s string128) Validate() error, cela fonctionne.

solution finale

func validateStruct(a interface{}) error { 
    v := reflect.ValueOf(a) 
    for i := 0; i < v.NumField(); i++ { 
     if _, ok := reflect.TypeOf(v.Field(i).Interface()).MethodByName("Validate"); ok { 
      err := reflect.ValueOf(v.Field(i).Interface()).MethodByName("Validate").Call([]reflect.Value{}) 
      if !err[0].IsNil() { 
       return err[0].Interface().(error) 
      } 
     } 
    } 
    return nil 
}