Go 语言通过反射获取结构体信息和结构体实例的地址
//获取结构体实例字段的地址
func GetFieldsOfStructAddr(s interface{}, filedNames []string) (res []interface{}, err error) {
v := reflect.ValueOf(s)
//如果传入指针则拿到指针指向的值
for v.Kind() == reflect.Ptr {
v = v.Elem()
}
//参数必须是结构体
for v.Kind() != reflect.Struct {
//防止panic,返回自定义错误
return
}
//v必须是一个实例
if !v.CanAddr() {
//防止panic,返回自定义错误
return
}
for _, filedName := range filedNames {
fieldValue := v.FieldByName(filedName)
if !fieldValue.CanAddr() {
//防止panic,返回自定义错误
return
}
res = append(res, fieldValue.Addr().Interface())
}
return
}
//获取结构体字段的变量名和tag名
func GetTagAndFiledNameOfStruct(s interface{}, tag string) (tagsRes []string, filedNames []string, err error) {
t := reflect.TypeOf(s)
//如果传入指针则拿到指针指向的值
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
//传入的必须是结构体
if t.Kind() != reflect.Struct {
return
}
//获取结构体字段数量
n := t.NumField()
for i := 0; i < n; i++ {
field := t.Field(i)
tagsRes = append(tagsRes, field.Tag.Get(tag))
filedNames = append(filedNames, field.Name)
}
return
}