调用方法属于struct的字段

时间:2017-09-14 10:07:57

标签: go reflection struct

我在Golang中有一些特殊类型,它代表一个带Validate方法的字符串。

type string128 string

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

结构体具有如下字段:

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
}

我想创建一个可以传递它们的函数,如果该字段有一个Validate()函数,则调用它。

我做了什么:

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
}

但是它有很多恐慌。

1 个答案:

答案 0 :(得分:0)

我发现了问题。只有当Validate函数没有指针接收器时,reflect.TypeOf(v.Field(i).Interface()).MethodByName("Validate")才能看到该函数,所以如果我将string128的Validate函数修改为func (s string128) Validate() error,它就可以了。

最终解决方案

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
}