如何在Go反射函数中处理[]*Struct类型字段,访问嵌入结构体
解决Go反射中处理[]*struct类型字段的加密字段统计问题
我们需要修改现有的getEncFields函数,使其能够处理元素为结构体指针的切片类型(比如[]*Address),递归统计其中带bson:"encr"标签的字段。
原函数的问题
原函数仅处理了指针和结构体类型,没有针对切片类型做逻辑分支,导致遇到[]*struct这类字段时无法深入遍历内部结构体的加密字段。
修改后的完整代码
import "strings" func getEncFields(t reflect.Type, list map[string]int) { // 先解多层指针 for t.Kind() == reflect.Ptr { t = t.Elem() } // 处理结构体类型:遍历字段 if t.Kind() == reflect.Struct { for i := 0; i < t.NumField(); i++ { field := t.Field(i) tag := field.Tag.Get("bson") if containsTag(tag, "encr") { list[getFieldName(field, tag)]++ } // 递归处理字段类型 getEncFields(field.Type, list) } } // 新增:处理切片类型,递归处理切片元素的类型 if t.Kind() == reflect.Slice { elemType := t.Elem() getEncFields(elemType, list) } } // 判断bson标签中是否包含指定标记 func containsTag(tag, target string) bool { parts := strings.Split(tag, ",") for _, p := range parts { if p == target { return true } } return false } // 从字段或bson标签中获取字段名 func getFieldName(field reflect.StructField, tag string) string { parts := strings.Split(tag, ",") if len(parts) > 0 && parts[0] != "" { return parts[0] } return field.Name }
改动说明
- 新增切片类型处理分支:当反射类型为
reflect.Slice时,获取切片的元素类型,递归调用getEncFields处理该元素类型。 - 复用指针解引用逻辑:函数开头的指针解循环会自动处理切片元素中的指针类型(比如
*Address),最终拿到底层的结构体类型进行遍历。 - 保持原有逻辑兼容:原有的结构体字段遍历、加密字段统计逻辑完全保留,不影响对普通结构体和指针字段的处理。
测试验证
使用示例结构体:
type Customer struct { Name string `json:"name" bson:"name"` Acnumber int64 `json:"acnumber" bson:"acnumber,encr"` Number int64 `json:"number" bson:"number,encr"` Address []*Address `json:"address" bson:"address"` } type Address struct { Mail string `json:"mail" bson:"mail,encr"` }
调用函数并输出结果:
func main() { encList := make(map[string]int) getEncFields(reflect.TypeOf(Customer{}), encList) fmt.Println(encList) // 输出:map[acnumber:1 mail:1 number:1] }
可以看到,Address切片内部的Mail字段已被正确统计。
内容的提问来源于stack exchange,提问作者Hariharan Panneerselvam
相关产品推荐
相关产品推荐

