123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- package utils
- import (
- "reflect"
- "strconv"
- "strings"
- "github.com/dablelv/go-huge-util/conv"
- jsoniter "github.com/json-iterator/go"
- "github.com/pkg/errors"
- "golang.org/x/exp/constraints"
- )
- var ComplexType = []reflect.Kind{reflect.Struct, reflect.Map, reflect.Slice, reflect.Array}
- // StructToMap 利用反射将结构体转化为map
- func StructToMap(structInfo any, tag string, stringify bool) (map[string]any, error) {
- val := reflect.Indirect(reflect.ValueOf(structInfo))
- smap := make(map[string]any)
- if err := ReflectToMap(smap, val, tag, stringify); err != nil {
- return nil, err
- }
- return smap, nil
- }
- // ReflectToMap 结构体反射转化成Map
- func ReflectToMap(smap map[string]any, val reflect.Value, tag string, stringify bool) error {
- typ := val.Type()
- if typ.Kind() != reflect.Struct {
- return errors.New("expect struct")
- }
- for i := 0; i < typ.NumField(); i++ {
- typField := typ.Field(i)
- if !typField.IsExported() {
- continue
- }
- if typField.Anonymous && typField.Type.Kind() == reflect.Struct {
- if err := ReflectToMap(smap, val.Field(i), tag, stringify); err != nil {
- return err
- }
- }
- tagName := typ.Field(i).Tag.Get(tag)
- if tagName == "" {
- continue
- }
- if stringify && IsComplexType(typField.Type) {
- marshal, err := jsoniter.Marshal(val.Field(i).Interface())
- if err != nil {
- return err
- }
- smap[tagName] = marshal
- } else {
- smap[tagName] = val.Field(i).Interface()
- }
- }
- return nil
- }
- // ArrayToMap 将数组转化为Map
- func ArrayToMap[T constraints.Ordered](array []T) map[string]any {
- mapArr := make(map[string]any, len(array))
- for i := 0; i < len(array); i++ {
- mapArr[strconv.Itoa(i)] = array[i]
- }
- return mapArr
- }
- // Indirect 若是指针 返回指针指向的 Value Type ; 不是指针直接返回 Value Type
- func Indirect(args any) (reflect.Value, reflect.Type) {
- val := reflect.ValueOf(args)
- typ := reflect.TypeOf(args)
- // 若是指针则取指针指向的值
- if val.Kind() == reflect.Ptr {
- val = val.Elem()
- typ = val.Type()
- }
- return val, typ
- }
- // Implode Join array elements with a string
- func Implode[T any](elems []T, sep string) string {
- joinEle := make([]string, 0, len(elems))
- for i := 0; i < len(elems); i++ {
- joinEle = append(joinEle, conv.ToAny[string](elems[i]))
- }
- return strings.Join(joinEle, sep)
- }
- // Explode Split a string by a string
- func Explode[T constraints.Ordered](dest *[]T, s string, sep string) (err error) {
- elems := strings.Split(s, sep)
- var elem T
- *dest = make([]T, 0, len(elems))
- for i := 0; i < len(elems); i++ {
- if elems[i] == "" {
- continue
- }
- if elem, err = conv.ToAnyE[T](elems[i]); err != nil {
- return err
- }
- *dest = append(*dest, elem)
- }
- return err
- }
- // TrimSpace 去除结构体空格
- // @param: target interface (target: 目标结构体,传入必须是指针类型)
- // @return: null
- func TrimSpace(target any) {
- t := reflect.TypeOf(target)
- if t.Kind() != reflect.Ptr {
- return
- }
- t = t.Elem()
- v := reflect.ValueOf(target).Elem()
- for i := 0; i < t.NumField(); i++ {
- switch v.Field(i).Kind() {
- case reflect.String:
- v.Field(i).SetString(strings.TrimSpace(v.Field(i).String()))
- }
- }
- }
|