TODO: 反射

This commit is contained in:
eson
2023-06-28 19:32:41 +08:00
parent 0851c922ef
commit d4e75b1efc
27 changed files with 527 additions and 186 deletions

View File

@@ -1,6 +1,7 @@
package collect
import (
"log"
"reflect"
"strconv"
)
@@ -111,7 +112,13 @@ func Array2MapByKey[KEY comparable, VALUE any](arrSrc []VALUE, fieldName string)
for i := 0; i < arr.Len(); i++ {
srcv := arr.Index(i)
fv := srcv.Elem().FieldByName(fieldName)
if srcv.Kind() == reflect.Ptr {
if srcv.IsNil() {
continue
}
srcv = srcv.Elem()
}
fv := srcv.FieldByName(fieldName)
k := fv.Interface().(KEY)
result[k] = srcv.Interface().(VALUE)
}
@@ -119,6 +126,7 @@ func Array2MapByKey[KEY comparable, VALUE any](arrSrc []VALUE, fieldName string)
return result
}
// 一个数组slice转换成 map[tag]slice ,以slice元素的某个tag为map
func Array2MapByKeyTag[KEY comparable, VALUE any](arrSrc []VALUE, tag string) (result map[KEY]VALUE) {
defer func() {
@@ -147,6 +155,9 @@ func Array2MapByKeyTag[KEY comparable, VALUE any](arrSrc []VALUE, tag string) (r
srcv := arr.Index(i)
var fv reflect.Value
if srcv.Kind() == reflect.Ptr {
if srcv.IsNil() {
continue
}
fv = srcv.Elem().Field(j)
} else {
fv = srcv.Field(j)
@@ -169,19 +180,20 @@ func Array2MapByKeyTag[KEY comparable, VALUE any](arrSrc []VALUE, tag string) (r
func StructJson2Map(s interface{}) map[string]interface{} {
t := reflect.TypeOf(s)
v := reflect.ValueOf(s)
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
var data = make(map[string]interface{})
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
if field.Tag == "" {
continue
if tag, ok := field.Tag.Lookup("json"); ok {
val := v.Field(i)
if val.Kind() == reflect.Ptr && !val.IsNil() {
val = val.Elem()
}
data[tag] = val.Interface()
}
tag := field.Tag.Get("json")
val := v.Field(i)
if val.Kind() == reflect.Ptr {
val = val.Elem()
}
data[tag] = val.Interface()
}
return data
}
@@ -193,7 +205,7 @@ func StructSliceJson2Maps(s interface{}) []map[string]interface{} {
for i := 0; i < slice.Len(); i++ {
s := slice.Index(i)
if s.Kind() == reflect.Ptr {
if s.Kind() == reflect.Ptr && !s.IsNil() {
s = s.Elem()
}
structValue := s.Interface()
@@ -202,3 +214,59 @@ func StructSliceJson2Maps(s interface{}) []map[string]interface{} {
}
return maps
}
func LoadJsonTag(v interface{}, loaded interface{}) {
vtype := reflect.TypeOf(v)
if vtype.Kind() == reflect.Ptr {
vtype = vtype.Elem()
}
vvalue := reflect.ValueOf(v)
if vvalue.Kind() == reflect.Ptr {
vvalue = vvalue.Elem()
}
ltype := reflect.TypeOf(loaded)
if ltype.Kind() == reflect.Ptr {
ltype = ltype.Elem()
}
lvalue := reflect.ValueOf(loaded)
if lvalue.Kind() == reflect.Ptr {
lvalue = lvalue.Elem()
}
for i := 0; i < vtype.NumField(); i++ {
vfield := vtype.Field(i)
if vtag, ok := vfield.Tag.Lookup("json"); ok {
for j := 0; j < ltype.NumField(); j++ {
lfield := ltype.Field(j)
if ltag, ok := lfield.Tag.Lookup("json"); ok && vtag == ltag {
vv := vvalue.Field(i)
lv := lvalue.Field(j)
log.Println(vv.Kind(), vv.Type().Elem(), lv.Kind())
if vv.Kind() == reflect.Ptr {
if lv.Kind() == reflect.Ptr {
vv.Set(lv)
} else {
vv = reflect.New(vv.Type().Elem())
log.Println(vv.Type().Kind(), vv.Elem().Kind(), lv, reflect.Indirect(vv))
reflect.Indirect(vv.Addr()).Set(lv.Addr())
vv = reflect.New(vv.Type().Elem())
vv.Set(lv.Addr())
}
vv.Set(lv)
} else {
if lv.Kind() != reflect.Ptr {
vv.Set(lv)
} else {
vv.Set(lv.Elem())
}
}
}
}
}
}
}