From e4cef0855e8af82d175af6af9a3179a2edbb2b0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Wed, 21 Aug 2024 17:09:00 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=8A=A8=E6=80=81=E7=94=9F=E6=88=90?= =?UTF-8?q?=E7=BB=93=E6=9E=84=E4=BD=93=E7=9A=84=E5=9F=BA=E7=A1=80=E8=83=BD?= =?UTF-8?q?=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dynamic_struct.go | 98 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 dynamic_struct.go diff --git a/dynamic_struct.go b/dynamic_struct.go new file mode 100644 index 0000000..3924d5e --- /dev/null +++ b/dynamic_struct.go @@ -0,0 +1,98 @@ +// Package wrapper ... +// +// Description : wrapper ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2024-08-21 16:43 +package wrapper + +import "reflect" + +func NewDynamic() *DynamicStruct { + return &DynamicStruct{ + structFieldList: make([]reflect.StructField, 0), + } +} + +// DynamicStruct 动态生成数据结构 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 16:48 2024/8/21 +type DynamicStruct struct { + structFieldList []reflect.StructField // 结构体字段列表 +} + +func (ds *DynamicStruct) AddInt() { + +} + +func (ds *DynamicStruct) AddUint() { + +} + +func (ds *DynamicStruct) AddString() { + +} + +func (ds *DynamicStruct) AddBool() { + +} + +func (ds *DynamicStruct) AddFloat() { + +} + +func (ds *DynamicStruct) AddSlice() { + +} + +func (ds *DynamicStruct) AddMap() { + +} + +func (ds *DynamicStruct) AddStructField() { + +} + +// 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() + defaultValue := reflect.New(ds.GetStructType()).Elem().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) +} From 18351f3b298cd6eef97ad225bf8457bf72801f8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Wed, 21 Aug 2024 18:16:21 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=AE=8C=E6=88=90v1=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8A=A8=E6=80=81=E7=BB=93=E6=9E=84=E4=BD=93=E5=88=9B=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dynamic_struct.go | 131 ++++++++++++++++++++++++++++++++++++----- dynamic_struct_test.go | 27 +++++++++ go.mod | 1 + go.sum | 2 + 4 files changed, 145 insertions(+), 16 deletions(-) create mode 100644 dynamic_struct_test.go diff --git a/dynamic_struct.go b/dynamic_struct.go index 3924d5e..904fe09 100644 --- a/dynamic_struct.go +++ b/dynamic_struct.go @@ -7,7 +7,10 @@ // Date : 2024-08-21 16:43 package wrapper -import "reflect" +import ( + "fmt" + "reflect" +) func NewDynamic() *DynamicStruct { return &DynamicStruct{ @@ -24,36 +27,132 @@ type DynamicStruct struct { structFieldList []reflect.StructField // 结构体字段列表 } -func (ds *DynamicStruct) AddInt() { - +// AddInt 添加int字段统一Int64 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 17:50 2024/8/21 +func (ds *DynamicStruct) AddInt(fieldName string, fieldTag string, pkgPath string) { + ds.AddStructField(reflect.StructField{ + Name: fieldName, + PkgPath: pkgPath, + Type: reflect.TypeOf(int64(0)), + Tag: reflect.StructTag(fmt.Sprintf(`json:"%v"`, fieldTag)), + }) } -func (ds *DynamicStruct) AddUint() { - +// AddUint 添加uint字段, 统一 uint64 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 17:50 2024/8/21 +func (ds *DynamicStruct) AddUint(fieldName string, fieldTag string, pkgPath string) { + ds.AddStructField(reflect.StructField{ + Name: fieldName, + PkgPath: pkgPath, + Type: reflect.TypeOf(uint64(0)), + Tag: reflect.StructTag(fieldTag), + }) } -func (ds *DynamicStruct) AddString() { - +// AddString 添加字符串字段 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 17:49 2024/8/21 +func (ds *DynamicStruct) AddString(fieldName string, fieldTag string, pkgPath string) { + ds.AddStructField(reflect.StructField{ + Name: fieldName, + PkgPath: pkgPath, + Type: reflect.TypeOf(""), + Tag: reflect.StructTag(fmt.Sprintf(`json:"%v"`, fieldTag)), + }) } -func (ds *DynamicStruct) AddBool() { - +// AddBool 添加bool字段 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 17:49 2024/8/21 +func (ds *DynamicStruct) AddBool(fieldName string, fieldTag string, pkgPath string) { + ds.AddStructField(reflect.StructField{ + Name: fieldName, + PkgPath: pkgPath, + Type: reflect.TypeOf(true), + Tag: reflect.StructTag(fmt.Sprintf(`json:"%v"`, fieldTag)), + }) } -func (ds *DynamicStruct) AddFloat() { - +// AddFloat 添加float字段, 统一 float64 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 17:48 2024/8/21 +func (ds *DynamicStruct) AddFloat(fieldName string, fieldTag string, pkgPath string) { + ds.AddStructField(reflect.StructField{ + Name: fieldName, + PkgPath: pkgPath, + Type: reflect.TypeOf(float64(0)), + Tag: reflect.StructTag(fmt.Sprintf(`json:"%v"`, fieldTag)), + }) } -func (ds *DynamicStruct) AddSlice() { - +// AddSlice 添加slice +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 17:47 2024/8/21 +func (ds *DynamicStruct) AddSlice(fieldName string, fieldTag string, pkgPath string) { + ds.AddStructField(reflect.StructField{ + Name: fieldName, + PkgPath: pkgPath, + Type: reflect.TypeOf([]any{}), + Tag: reflect.StructTag(fieldTag), + }) } -func (ds *DynamicStruct) AddMap() { - +// AddMap 添加map字段 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 17:43 2024/8/21 +func (ds *DynamicStruct) AddMap(fieldName string, fieldTag string, pkgPath string) { + ds.AddStructField(reflect.StructField{ + Name: fieldName, + PkgPath: pkgPath, + Type: reflect.TypeOf(map[string]any{}), + Tag: reflect.StructTag(fieldTag), + }) } -func (ds *DynamicStruct) AddStructField() { +// 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), + }) +} +// AddStructField 添加结构体字段 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 17:42 2024/8/21 +func (ds *DynamicStruct) AddStructField(field reflect.StructField) { + if field.Tag == "" { + field.Tag = reflect.StructTag(fmt.Sprintf(`json:"%v"`, field.Name)) + } + ds.structFieldList = append(ds.structFieldList, field) } // GetStructType 获取结构体的类型 diff --git a/dynamic_struct_test.go b/dynamic_struct_test.go new file mode 100644 index 0000000..af3cfec --- /dev/null +++ b/dynamic_struct_test.go @@ -0,0 +1,27 @@ +// 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", "") + instance.AddString("Name", "name", "") + defaultVal := instance.ToStructDefaultValue() + testMap := map[string]any{ + "name": "白茶", + "age": 18, + } + _ = mapstructure.Decode(testMap, &defaultVal) + fmt.Println(defaultVal) +} diff --git a/go.mod b/go.mod index dcc9a44..e21ee1b 100644 --- a/go.mod +++ b/go.mod @@ -21,6 +21,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-ini/ini v1.67.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mozillazg/go-pinyin v0.20.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/tidwall/match v1.1.1 // indirect diff --git a/go.sum b/go.sum index 4a51eac..edc9cc6 100644 --- a/go.sum +++ b/go.sum @@ -38,6 +38,8 @@ github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mozillazg/go-pinyin v0.20.0 h1:BtR3DsxpApHfKReaPO1fCqF4pThRwH9uwvXzm+GnMFQ= github.com/mozillazg/go-pinyin v0.20.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=