调用方法属于struct的领域

I have some special type in Golang what represent a string with Validate method.

type string128 string

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

There is structs have fields like the following:

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
}

I want to make a function where I can pass them and if the field have a Validate() function call it.

What I have done:

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
}

But it is do a lots of panic.

I found the problem. The reflect.TypeOf(v.Field(i).Interface()).MethodByName("Validate") see the function only if the Validate function doesn't have pointer receiver so if I modify the Validate function of the string128 to func (s string128) Validate() error, it is working.

Final solution

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
}