feature/upgrade_dynamic_struct #9
							
								
								
									
										4
									
								
								any.go
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								any.go
									
									
									
									
									
								
							| @ -87,7 +87,7 @@ func (at *AnyType) Type() consts.DataType { | |||||||
| 	case reflect.Bool: | 	case reflect.Bool: | ||||||
| 		return consts.DataTypeBool | 		return consts.DataTypeBool | ||||||
| 	case reflect.Float32, reflect.Float64: | 	case reflect.Float32, reflect.Float64: | ||||||
| 		return consts.DataTypeFloat | 		return consts.DataTypeFloat64 | ||||||
| 	default: | 	default: | ||||||
| 		return consts.DataTypeUnknown | 		return consts.DataTypeUnknown | ||||||
| 	} | 	} | ||||||
| @ -116,7 +116,7 @@ func (at *AnyType) ToString() String { | |||||||
| 		return String(Int(at.data.(int64)).ToString().Value) | 		return String(Int(at.data.(int64)).ToString().Value) | ||||||
| 	case consts.DataTypeUint: | 	case consts.DataTypeUint: | ||||||
| 		return String(Int(at.data.(uint)).ToString().Value) | 		return String(Int(at.data.(uint)).ToString().Value) | ||||||
| 	case consts.DataTypeFloat: | 	case consts.DataTypeFloat64: | ||||||
| 		return String(Float(at.data.(float64)).ToString().Value) | 		return String(Float(at.data.(float64)).ToString().Value) | ||||||
| 	case consts.DataTypeBool: | 	case consts.DataTypeBool: | ||||||
| 		return String(fmt.Sprintf("%v", at.data)) | 		return String(fmt.Sprintf("%v", at.data)) | ||||||
|  | |||||||
| @ -1,255 +0,0 @@ | |||||||
| // Package wrapper ... |  | ||||||
| // |  | ||||||
| // Description : wrapper ... |  | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 2024-08-21 16:43 |  | ||||||
| package wrapper |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"encoding/json" |  | ||||||
| 	"fmt" |  | ||||||
| 	"reflect" |  | ||||||
| 	"sync" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // NewMap2DynamicStruct 通过map生成动态结构体 |  | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 18:48 2025/1/24 |  | ||||||
| func NewMap2DynamicStruct(mapData map[string]any, tagTable map[string]string) *DynamicStruct { |  | ||||||
| 	d := NewDynamic() |  | ||||||
| 	d.mapData = mapData |  | ||||||
| 	for k, v := range mapData { |  | ||||||
| 		d.AddAny(String(k).SnakeCaseToCamel(), tagTable[k], "dynamic_struct", v) |  | ||||||
| 	} |  | ||||||
| 	return d |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func NewDynamic() *DynamicStruct { |  | ||||||
| 	return &DynamicStruct{ |  | ||||||
| 		structFieldList: make([]reflect.StructField, 0), |  | ||||||
| 		mapData:         make(map[string]any), |  | ||||||
| 		l:               &sync.RWMutex{}, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // DynamicStruct 动态生成数据结构 |  | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 16:48 2024/8/21 |  | ||||||
| type DynamicStruct struct { |  | ||||||
| 	structFieldList []reflect.StructField // 结构体字段列表 |  | ||||||
| 	mapData         map[string]any |  | ||||||
| 	l               *sync.RWMutex |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // SetMapData 设置map值 |  | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 18:50 2025/1/24 |  | ||||||
| func (ds *DynamicStruct) SetMapData(field string, value any) { |  | ||||||
| 	ds.l.Lock() |  | ||||||
| 	defer ds.l.Unlock() |  | ||||||
| 	ds.mapData[field] = value |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AddInt 添加int字段统一Int64 |  | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 17:50 2024/8/21 |  | ||||||
| func (ds *DynamicStruct) AddInt(fieldName string, fieldTag string, pkgPath string, value int64) { |  | ||||||
| 	ds.AddStructField(reflect.StructField{ |  | ||||||
| 		Name:    fieldName, |  | ||||||
| 		PkgPath: pkgPath, |  | ||||||
| 		Type:    reflect.TypeOf(int64(0)), |  | ||||||
| 		Tag:     reflect.StructTag(fieldTag), |  | ||||||
| 	}, value) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AddUint 添加uint字段, 统一 uint64 |  | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 17:50 2024/8/21 |  | ||||||
| func (ds *DynamicStruct) AddUint(fieldName string, fieldTag string, pkgPath string, val uint64) { |  | ||||||
| 	ds.AddStructField(reflect.StructField{ |  | ||||||
| 		Name:    fieldName, |  | ||||||
| 		PkgPath: pkgPath, |  | ||||||
| 		Type:    reflect.TypeOf(uint64(0)), |  | ||||||
| 		Tag:     reflect.StructTag(fieldTag), |  | ||||||
| 	}, val) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AddString 添加字符串字段 |  | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 17:49 2024/8/21 |  | ||||||
| func (ds *DynamicStruct) AddString(fieldName string, fieldTag string, pkgPath string, val string) { |  | ||||||
| 	ds.AddStructField(reflect.StructField{ |  | ||||||
| 		Name:    fieldName, |  | ||||||
| 		PkgPath: pkgPath, |  | ||||||
| 		Type:    reflect.TypeOf(""), |  | ||||||
| 		Tag:     reflect.StructTag(fieldTag), |  | ||||||
| 	}, val) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AddBool 添加bool字段 |  | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 17:49 2024/8/21 |  | ||||||
| func (ds *DynamicStruct) AddBool(fieldName string, fieldTag string, pkgPath string, val bool) { |  | ||||||
| 	ds.AddStructField(reflect.StructField{ |  | ||||||
| 		Name:    fieldName, |  | ||||||
| 		PkgPath: pkgPath, |  | ||||||
| 		Type:    reflect.TypeOf(true), |  | ||||||
| 		Tag:     reflect.StructTag(fmt.Sprintf(`json:"%v"`, fieldTag)), |  | ||||||
| 	}, val) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AddFloat 添加float字段, 统一 float64 |  | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 17:48 2024/8/21 |  | ||||||
| func (ds *DynamicStruct) AddFloat(fieldName string, fieldTag string, pkgPath string, val float64) { |  | ||||||
| 	ds.AddStructField(reflect.StructField{ |  | ||||||
| 		Name:    fieldName, |  | ||||||
| 		PkgPath: pkgPath, |  | ||||||
| 		Type:    reflect.TypeOf(float64(0)), |  | ||||||
| 		Tag:     reflect.StructTag(fieldTag), |  | ||||||
| 	}, val) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AddSlice 添加slice |  | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 17:47 2024/8/21 |  | ||||||
| func (ds *DynamicStruct) AddSlice(fieldName string, fieldTag string, pkgPath string, val any) { |  | ||||||
| 	ds.AddStructField(reflect.StructField{ |  | ||||||
| 		Name:    fieldName, |  | ||||||
| 		PkgPath: pkgPath, |  | ||||||
| 		Type:    reflect.TypeOf([]any{}), |  | ||||||
| 		Tag:     reflect.StructTag(fieldTag), |  | ||||||
| 	}, val) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AddMap 添加map字段 |  | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 17:43 2024/8/21 |  | ||||||
| func (ds *DynamicStruct) AddMap(fieldName string, fieldTag string, pkgPath string, val any) { |  | ||||||
| 	ds.AddStructField(reflect.StructField{ |  | ||||||
| 		Name:    fieldName, |  | ||||||
| 		PkgPath: pkgPath, |  | ||||||
| 		Type:    reflect.TypeOf(map[string]any{}), |  | ||||||
| 		Tag:     reflect.StructTag(fieldTag), |  | ||||||
| 	}, val) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AddAny 添加任意类型字段 |  | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 17:52 2024/8/21 |  | ||||||
| func (ds *DynamicStruct) AddAny(fieldName string, fieldTag string, pkgPath string, value any) { |  | ||||||
| 	if nil == value { |  | ||||||
| 		// 不能是空指针 |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	ds.AddStructField(reflect.StructField{ |  | ||||||
| 		Name:    fieldName, |  | ||||||
| 		PkgPath: pkgPath, |  | ||||||
| 		Type:    reflect.TypeOf(value), |  | ||||||
| 		Tag:     reflect.StructTag(fieldTag), |  | ||||||
| 	}, value) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AddStructField 添加结构体字段 |  | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 17:42 2024/8/21 |  | ||||||
| func (ds *DynamicStruct) AddStructField(field reflect.StructField, fieldValue any) { |  | ||||||
| 	if field.Tag == "" { |  | ||||||
| 		field.Tag = reflect.StructTag(fmt.Sprintf(`json:"%v"`, field.Name)) |  | ||||||
| 	} |  | ||||||
| 	ds.SetMapData(field.Name, fieldValue) |  | ||||||
| 	field.Name = String(field.Name).SnakeCaseToCamel() // 转成大驼峰, 保证对外可访问 |  | ||||||
| 	ds.structFieldList = append(ds.structFieldList, field) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GetStructType 获取结构体的类型 |  | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 16:58 2024/8/21 |  | ||||||
| func (ds *DynamicStruct) GetStructType() reflect.Type { |  | ||||||
| 	return reflect.StructOf(ds.structFieldList) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ToStructDefaultValue 获取结构体的值, 并采用对应类型默认值填充相关字段 |  | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 16:56 2024/8/21 |  | ||||||
| func (ds *DynamicStruct) ToStructDefaultValue() any { |  | ||||||
| 	defer ds.Clear() |  | ||||||
| 	reflectValue := reflect.New(ds.GetStructType()).Elem() |  | ||||||
| 	if len(ds.mapData) > 0 { |  | ||||||
| 		// 开始赋值 |  | ||||||
| 		for field, val := range ds.mapData { |  | ||||||
| 			realField := String(field).SnakeCaseToCamel() |  | ||||||
| 			findFieldValue := reflectValue.FieldByName(realField) |  | ||||||
| 			if findFieldValue.CanSet() { |  | ||||||
| 				findFieldValue.Set(reflect.ValueOf(val)) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	defaultValue := reflectValue.Interface() |  | ||||||
| 	return defaultValue |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ToStructDefaultSliceValue 自动生成结构体列表 |  | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 17:04 2024/8/21 |  | ||||||
| func (ds *DynamicStruct) ToStructDefaultSliceValue() any { |  | ||||||
| 	defer ds.Clear() |  | ||||||
| 	tSlice := reflect.MakeSlice(reflect.SliceOf(ds.GetStructType()), 0, 0) |  | ||||||
| 	return reflect.New(tSlice.Type()).Elem().Interface() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Clear 清理 |  | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 17:08 2024/8/21 |  | ||||||
| func (ds *DynamicStruct) Clear() { |  | ||||||
| 	// 清理掉已设置的字段, 不然实例复用会互相影响 |  | ||||||
| 	ds.structFieldList = make([]reflect.StructField, 0) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // MarshalJSON 自定义的序列化方法 |  | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 18:47 2025/1/24 |  | ||||||
| func (ds *DynamicStruct) MarshalJSON() ([]byte, error) { |  | ||||||
| 	return json.Marshal(ds.mapData) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // MapData map数据 |  | ||||||
| func (ds *DynamicStruct) MapData() (map[string]any) { |  | ||||||
| 	return ds.mapData |  | ||||||
| } |  | ||||||
| @ -1,27 +0,0 @@ | |||||||
| // Package wrapper ... |  | ||||||
| // |  | ||||||
| // Description : wrapper ... |  | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 2024-08-21 17:56 |  | ||||||
| package wrapper |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"fmt" |  | ||||||
| 	"github.com/mitchellh/mapstructure" |  | ||||||
| 	"testing" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func TestNewDynamic(t *testing.T) { |  | ||||||
| 	instance := NewDynamic() |  | ||||||
| 	instance.AddInt("Age", "age", "", 0) |  | ||||||
| 	instance.AddString("Name", "name", "", "test") |  | ||||||
| 	defaultVal := instance.ToStructDefaultValue() |  | ||||||
| 	testMap := map[string]any{ |  | ||||||
| 		"name": "白茶", |  | ||||||
| 		"age":  18, |  | ||||||
| 	} |  | ||||||
| 	_ = mapstructure.Decode(testMap, &defaultVal) |  | ||||||
| 	fmt.Println(defaultVal) |  | ||||||
| } |  | ||||||
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							| @ -5,7 +5,7 @@ go 1.21 | |||||||
| toolchain go1.21.4 | toolchain go1.21.4 | ||||||
|  |  | ||||||
| require ( | require ( | ||||||
| 	git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250227040546-863c03f34bb8 | 	git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250321102241-d6e86b64f7ca | ||||||
| 	git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 | 	git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 | ||||||
| 	git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd | 	git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd | ||||||
| 	git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e | 	git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.sum
									
									
									
									
									
								
							| @ -10,6 +10,8 @@ git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250122075709-5ecf3edb4a00 h1:obyJF0 | |||||||
| git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250122075709-5ecf3edb4a00/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k= | git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250122075709-5ecf3edb4a00/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k= | ||||||
| git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250227040546-863c03f34bb8 h1:VEifPc+vkpEQoX9rj7zxmT1m+IA81XjOxe7+Z1aqWNM= | git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250227040546-863c03f34bb8 h1:VEifPc+vkpEQoX9rj7zxmT1m+IA81XjOxe7+Z1aqWNM= | ||||||
| git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250227040546-863c03f34bb8/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k= | git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250227040546-863c03f34bb8/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k= | ||||||
|  | git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250321102241-d6e86b64f7ca h1:uxjzbY5fDozjyK6jkoQtuQouVTcVfXjbe3chARYSjRM= | ||||||
|  | git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250321102241-d6e86b64f7ca/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k= | ||||||
| git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 h1:gUDlQMuJ4xNfP2Abl1Msmpa3fASLWYkNlqDFF/6GN0Y= | git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 h1:gUDlQMuJ4xNfP2Abl1Msmpa3fASLWYkNlqDFF/6GN0Y= | ||||||
| git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0/go.mod h1:VHb9qmhaPDAQDcS6vUiDCamYjZ4R5lD1XtVsh55KsMI= | git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0/go.mod h1:VHb9qmhaPDAQDcS6vUiDCamYjZ4R5lD1XtVsh55KsMI= | ||||||
| git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241104092308-ecb02113459e h1:A045F67AMSqFKGD9kk2uLa+6c/zpmW8vjjSRmSsdjPs= | git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241104092308-ecb02113459e h1:A045F67AMSqFKGD9kk2uLa+6c/zpmW8vjjSRmSsdjPs= | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user