package structx import ( "encoding/json" "fmt" "reflect" "strconv" "code.yun.ink/pkg/convx" ) // converterFunc 类型转换函数 type converterFunc func(reflect.Value, string) (interface{}, error) var ( typeConverters = map[reflect.Kind]converterFunc{ reflect.Bool: convertBool, reflect.Int: convertInt[int], reflect.Int8: convertInt[int8], reflect.Int16: convertInt[int16], reflect.Int32: convertInt[int32], reflect.Int64: convertInt[int64], reflect.Uint: convertUint[uint], reflect.Uint8: convertUint[uint8], reflect.Uint16: convertUint[uint16], reflect.Uint32: convertUint[uint32], reflect.Uint64: convertUint[uint64], reflect.Float32: convertFloat[float32], reflect.Float64: convertFloat[float64], reflect.String: convertString, reflect.Slice: convertSlice, reflect.Array: convertArray, reflect.Map: convertMap, } ) // 转换为字符串 func convertToString(item interface{}) string { if str, ok := item.(string); ok { return str } return fmt.Sprintf("%v", item) } // 转换为数字(float64) func convertToFloat64(item interface{}) (float64, error) { switch v := item.(type) { case float64: return v, nil case int, int32, int64: return float64(reflect.ValueOf(v).Int()), nil case uint, uint32, uint64: return float64(reflect.ValueOf(v).Uint()), nil case float32: return float64(v), nil default: return 0, fmt.Errorf("无法转换为数字") } } // 转换为类型别名 func convertToTypeAlias(aliasType reflect.Type, value interface{}) (interface{}, error) { if aliasType.Kind() == reflect.Ptr { elemType := aliasType.Elem() newValue := reflect.New(elemType) elemValue := newValue.Elem() converted, err := convertValueToType(value, elemType) if err != nil { return nil, err } elemValue.Set(reflect.ValueOf(converted)) return newValue.Interface(), nil } return convertValueToType(value, aliasType) } // 转换值为目标类型 func convertValueToType(value interface{}, targetType reflect.Type) (interface{}, error) { valueType := reflect.TypeOf(value) if valueType.AssignableTo(targetType) { return value, nil } if valueType.ConvertibleTo(targetType) { return reflect.ValueOf(value).Convert(targetType).Interface(), nil } return nil, fmt.Errorf("无法转换类型") } // 类型转换函数 func convertBool(field reflect.Value, value string) (interface{}, error) { return convx.ToBool(value) } func convertInt[T int | int8 | int16 | int32 | int64](field reflect.Value, value string) (interface{}, error) { bits := field.Type().Bits() intVal, err := strconv.ParseInt(value, 10, bits) if err != nil { return nil, err } return T(intVal), nil } func convertUint[T uint | uint8 | uint16 | uint32 | uint64](field reflect.Value, value string) (interface{}, error) { bits := field.Type().Bits() uintVal, err := strconv.ParseUint(value, 10, bits) if err != nil { return nil, err } return T(uintVal), nil } func convertFloat[T float32 | float64](field reflect.Value, value string) (interface{}, error) { bits := field.Type().Bits() floatVal, err := strconv.ParseFloat(value, bits) if err != nil { return nil, err } return T(floatVal), nil } func convertString(field reflect.Value, value string) (interface{}, error) { return value, nil } func convertSlice(field reflect.Value, value string) (interface{}, error) { var result []interface{} if err := json.Unmarshal([]byte(value), &result); err != nil { return nil, err } return result, nil } func convertArray(field reflect.Value, value string) (interface{}, error) { var result []interface{} if err := json.Unmarshal([]byte(value), &result); err != nil { return nil, err } return result, nil } func convertMap(field reflect.Value, value string) (interface{}, error) { return nil, fmt.Errorf("map转换未实现") } func getBaseTypeFromAlias(aliasType reflect.Type) reflect.Type { if aliasType.Kind() == reflect.Ptr { aliasType = aliasType.Elem() } switch aliasType.Kind() { case reflect.String: return reflect.TypeOf("") case reflect.Int: return reflect.TypeOf(int(0)) case reflect.Int8: return reflect.TypeOf(int8(0)) case reflect.Int16: return reflect.TypeOf(int16(0)) case reflect.Int32: return reflect.TypeOf(int32(0)) case reflect.Int64: return reflect.TypeOf(int64(0)) case reflect.Uint: return reflect.TypeOf(uint(0)) case reflect.Uint8: return reflect.TypeOf(uint8(0)) case reflect.Uint16: return reflect.TypeOf(uint16(0)) case reflect.Uint32: return reflect.TypeOf(uint32(0)) case reflect.Uint64: return reflect.TypeOf(uint64(0)) case reflect.Float32: return reflect.TypeOf(float32(0)) case reflect.Float64: return reflect.TypeOf(float64(0)) case reflect.Bool: return reflect.TypeOf(false) default: return nil } }