package serialization import ( "encoding/json" "fmt" "reflect" "strconv" ) func StructToMap(obj interface{}) map[string]interface{} { out := make(map[string]interface{}) v := reflect.ValueOf(obj) if v.Kind() == reflect.Ptr { v = v.Elem() } t := v.Type() for i := 0; i < v.NumField(); i++ { field := t.Field(i) key := field.Tag.Get("json") // 使用 json tag 作为字段名 if key == "" { key = field.Name } out[key] = v.Field(i).Interface() } return out } func keyValueToField(key, value string, fieldValue *reflect.Value) error { switch fieldValue.Kind() { case reflect.Int8, reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64: if v, err := strconv.ParseInt(value, 10, 0); err == nil { fieldValue.SetInt(v) } else { return err } case reflect.Uint8, reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: if v, err := strconv.ParseUint(value, 10, 0); err == nil { fieldValue.SetUint(v) } else { return err } case reflect.Float32, reflect.Float64: if v, err := strconv.ParseFloat(value, 0); err == nil { fieldValue.SetFloat(v) } else { return err } case reflect.String: fieldValue.SetString(value) case reflect.Bool: if v, err := strconv.ParseBool(value); err == nil { fieldValue.SetBool(v) } else { return err } default: nv := reflect.New(fieldValue.Type()) if err := json.Unmarshal([]byte(value), nv.Interface()); err == nil { if fieldValue.Kind() == nv.Elem().Kind() { fieldValue.Set(nv.Elem()) } else { return fmt.Errorf("field:%v should have same type.original type:%v, reflect type:%v", key, fieldValue.Kind().String(), nv.Elem().Kind().String()) } } else { return err } } return nil } func deserializeMapString(kvs map[string]string, structObj interface{}) error { val := reflect.ValueOf(structObj).Elem() typ := val.Type() for i := 0; i < typ.NumField(); i++ { field := typ.Field(i) // 检查字段是否可设置(即导出) if !field.IsExported() { continue } fieldName := field.Tag.Get("json") if fieldName == "-" { continue } if value, ok := kvs[fieldName]; ok { // 获取字段的反射值 fieldValue := val.FieldByName(field.Name) if err := keyValueToField(field.Tag.Get("json"), value, &fieldValue); err != nil { return err } } else { return fmt.Errorf("redis:%v not has field:%v ", typ.Name(), field.Tag.Get("json")) } } return nil } type resultT[T any] struct { ret T } func MapStringToStruct[T any](maps map[string]string) (*T, error) { result := &resultT[T]{} err := deserializeMapString(maps, &result.ret) return &result.ret, err }