package dynamicstruct import ( "reflect" "strings" ) type ( // Builder 运行时动态生成结构体的接口约束 Builder interface { // AddField 添加结构体字段 AddField(name string, pkg string, typ any, tag string, anonymous bool) Builder // RemoveField 移除指定名称的结构体字段 RemoveField(name string) Builder // HasField 检测指定名称的结构体字段是否存在 HasField(name string) bool // GetField 根据名称获取结构体字段定义 GetField(name string) FieldConfig // Build 返回动态定义的结构体. Build() DynamicStruct } // FieldConfig 结构体字段的定义. FieldConfig interface { // SetType 设置字段类型. SetType(typ any) FieldConfig // SetTag 设置字段 tag. SetTag(tag string) FieldConfig } // DynamicStruct contains defined dynamic struct. // This definition can't be changed anymore, once is built. // It provides a method for creating new instances of same defintion. DynamicStruct interface { // New 获取结构体实例, 所有字段值均为对应类型的初始零值 New() any // NewSliceOfStructs slice实例化 NewSliceOfStructs() any // NewMapOfStructs map 或者 struct实例化 NewMapOfStructs(key any) any } builderImpl struct { fields []*fieldConfigImpl } fieldConfigImpl struct { name string pkg string typ any tag string anonymous bool } dynamicStructImpl struct { definition reflect.Type } ) // NewStruct 获取builder实例 func NewStruct() Builder { return &builderImpl{ fields: []*fieldConfigImpl{}, } } // ExtendStruct 基于已有结构体, 生成动态结构体(相当于继承指定的结构体属性) func ExtendStruct(value ...any) Builder { return MergeStructs(value...) } // MergeStructs 多个结构体合并成一个动态结构体 func MergeStructs(values ...any) Builder { builder := NewStruct() for _, value := range values { valueOf := reflect.Indirect(reflect.ValueOf(value)) typeOf := valueOf.Type() for i := 0; i < valueOf.NumField(); i++ { fVal := valueOf.Field(i) fTyp := typeOf.Field(i) builder.(*builderImpl).AddField(fTyp.Name, fTyp.PkgPath, fVal.Interface(), string(fTyp.Tag), fTyp.Anonymous) } } return builder } // IsNestedField 判断是否是嵌套结构体 func (b *builderImpl) parseNestedField(fieldName string) ([]string, bool) { fieldNameArr := strings.Split(strings.Trim(fieldName, "."), ".") return fieldNameArr, len(fieldNameArr) > 1 } // AddField 添加结构体字段 func (b *builderImpl) AddField(name string, pkg string, typ any, tag string, anonymous bool) Builder { // 判断是否嵌套结构体 fieldNameArr, isNestedField := b.parseNestedField(name) if !isNestedField { // 普通字段 b.addNormalField(name, pkg, typ, tag, anonymous) return b } // TODO : 添加嵌套的结构体 b.addNestedField(fieldNameArr, pkg, typ, tag, anonymous) return b } // addNormalField 添加普通无嵌套的字段 func (b *builderImpl) addNormalField(name string, pkg string, typ any, tag string, anonymous bool) { if existFieldCfg := b.GetField(name); nil != existFieldCfg { // 说明已存在指定名称字段 // 重复添加, 则会议后面的标签以及类型, 覆盖前面的值 existFieldCfg.SetTag(tag) existFieldCfg.SetType(typ) return } b.fields = append(b.fields, &fieldConfigImpl{ name: name, typ: typ, tag: tag, anonymous: anonymous, pkg: pkg, }) } // addNestedField 添加嵌套字段 func (b *builderImpl) addNestedField(nameArr []string, pkg string, typ any, tag string, anonymous bool) { } // RemoveField 根据名称移除结构体字段 func (b *builderImpl) RemoveField(name string) Builder { newFieldList := make([]*fieldConfigImpl, 0) for i := range b.fields { if b.fields[i].name == name { continue } newFieldList = append(newFieldList, b.fields[i]) } b.fields = newFieldList return b } // HasField 是否存在指定字段 func (b *builderImpl) HasField(name string) bool { for i := range b.fields { if b.fields[i].name == name { return true } } return false } // GetField 根据名称获取字段配置, 不存在, 返回nil func (b *builderImpl) GetField(name string) FieldConfig { for i := range b.fields { if b.fields[i].name == name { return b.fields[i] } } return nil } // Build 构建动态结构体 func (b *builderImpl) Build() DynamicStruct { var structFields []reflect.StructField for _, field := range b.fields { structFields = append(structFields, reflect.StructField{ Name: field.name, PkgPath: field.pkg, Type: reflect.TypeOf(field.typ), Tag: reflect.StructTag(field.tag), Anonymous: field.anonymous, }) } return &dynamicStructImpl{ definition: reflect.StructOf(structFields), } } // SetType 设置字段类型 func (f *fieldConfigImpl) SetType(typ any) FieldConfig { f.typ = typ return f } // SetTag 设置字段标签 func (f *fieldConfigImpl) SetTag(tag string) FieldConfig { f.tag = tag return f } // New 创建动态结构体实例 func (ds *dynamicStructImpl) New() any { return reflect.New(ds.definition).Interface() } // NewSliceOfStructs 创建动态结构体切片实例 func (ds *dynamicStructImpl) NewSliceOfStructs() any { return reflect.New(reflect.SliceOf(ds.definition)).Interface() } // NewMapOfStructs 创建动态结构体map实例 func (ds *dynamicStructImpl) NewMapOfStructs(key any) any { return reflect.New(reflect.MapOf(reflect.Indirect(reflect.ValueOf(key)).Type(), ds.definition)).Interface() }