package reflectutils import ( "github.com/pkg/errors" "reflect" "strconv" ) // GroupValueKind 将反射的Kind值进行聚集 func GroupValueKind(v reflect.Value) reflect.Kind { kind := v.Kind() switch { case kind >= reflect.Int && kind <= reflect.Int64: return reflect.Int64 case kind >= reflect.Uint && kind <= reflect.Uint64: return reflect.Uint64 case kind >= reflect.Float32 && kind <= reflect.Float64: return reflect.Float64 default: return kind } } func PointerValueElem(v reflect.Value) reflect.Value { elem := v if v.Kind() == reflect.Ptr { elem = v.Elem() } return elem } func SliceValueElem(v reflect.Value) reflect.Value { elem := v if v.Kind() == reflect.Slice { elem = v.Elem() } return elem } func IsSliceValueOf(v reflect.Value, elementKind reflect.Kind) bool { return v.Kind() == reflect.Slice && v.Type().Elem().Kind() == elementKind } func IsValueInteger(v reflect.Value) bool { return v.Kind() >= reflect.Int && v.Kind() <= reflect.Int64 } func IsValueUnsignedInteger(v reflect.Value) bool { return v.Kind() >= reflect.Uint && v.Kind() <= reflect.Uint64 } func IsValueFloat(v reflect.Value) bool { return v.Kind() >= reflect.Float32 && v.Kind() <= reflect.Float64 } func IsValueStructPointer(v reflect.Value) bool { return v.Kind() == reflect.Pointer && v.Elem().Kind() == reflect.Struct } func IsValueStructOrStructPointer(v reflect.Value) bool { return v.Kind() == reflect.Struct || IsValueStructPointer(v) } func IsValueStructSliceOrStructSlicePointer(v reflect.Value) bool { return IsSliceValueOf(v, reflect.Struct) || (v.Kind() == reflect.Pointer && IsSliceValueOf(v.Elem(), reflect.Struct)) } func IsValueTime(v reflect.Value) bool { return v.Kind() == reflect.Struct && v.Type().String() == "time.Time" } func IsValueTimePointer(v reflect.Value) bool { return v.Kind() == reflect.Pointer && IsValueTime(v.Elem()) } // AssignStringValue 将any类型的值进行转化,赋值给string的reflect.Value func AssignStringValue(data any, val reflect.Value) error { if data == nil { return nil } if val.Kind() != reflect.String { return errors.New("val应当为string类型的Value") } v, err := ToString(data) if err != nil { return err } val.SetString(v) return nil } // AssignInt64Value 将any类型的值进行转化,赋值给int64类型的reflect.Value func AssignInt64Value(data any, val reflect.Value) error { if data == nil { return nil } if val.Kind() < reflect.Int && val.Kind() > reflect.Int64 { return errors.New("val应当为int类型的Value") } v, err := ToInt64(data) if err != nil { return err } val.SetInt(v) return nil } // AssignUint64Value 将any类型的值进行转化,赋值给uint64类型的reflect.Value func AssignUint64Value(data any, val reflect.Value) error { if data == nil { return nil } if val.Kind() < reflect.Uint && val.Kind() > reflect.Uint64 { return errors.New("val应当为uint类型的Value") } v, err := ToUint64(data) if err != nil { return err } val.SetUint(v) return nil } // AssignBoolValue 将any类型的值进行转化,赋值给bool类型的reflect.Value func AssignBoolValue(data any, val reflect.Value) error { if data == nil { return nil } if val.Kind() != reflect.Bool { return errors.New("val应当为bool类型的Value") } v, err := ToBool(data) if err != nil { return err } val.SetBool(v) return nil } // AssignFloat64Value 将any类型的值进行转化,赋值给float64类型的reflect.Value func AssignFloat64Value(data any, val reflect.Value) error { if data == nil { return nil } if val.Kind() != reflect.Float32 && val.Kind() != reflect.Float64 { return errors.New("val应当为float类型的Value") } v, err := ToFloat64(data) if err != nil { return err } val.SetFloat(v) return nil } // ToString 将any类型的值进行转化为string类型 func ToString(data any) (string, error) { if data == nil { return "", nil } dataVal := reflect.Indirect(reflect.ValueOf(data)) dataKind := GroupValueKind(dataVal) switch dataKind { case reflect.String: return dataVal.String(), nil case reflect.Bool: if dataVal.Bool() { return "1", nil } else { return "0", nil } case reflect.Int64: return strconv.FormatInt(dataVal.Int(), 10), nil case reflect.Uint64: return strconv.FormatUint(dataVal.Uint(), 10), nil case reflect.Float64: return strconv.FormatFloat(dataVal.Float(), 'f', -1, 64), nil case reflect.Slice, reflect.Array: elemKind := dataVal.Type().Elem().Kind() if elemKind != reflect.Uint8 { return "", errors.New("不支持的类型: " + dataVal.Type().Elem().String()) } var uints []uint8 if dataKind == reflect.Array { uints = make([]uint8, dataVal.Len(), dataVal.Len()) for i := range uints { uints[i] = dataVal.Index(i).Interface().(uint8) } } else { uints = dataVal.Interface().([]uint8) } return string(uints), nil default: return "", errors.New("不支持的类型: " + dataVal.Type().Elem().String()) } } // ToInt64 将any类型的值进行转化为int64类型 func ToInt64(data any) (int64, error) { if data == nil { return 0, nil } dataVal := reflect.Indirect(reflect.ValueOf(data)) dataKind := GroupValueKind(dataVal) switch dataKind { case reflect.Int64: return dataVal.Int(), nil case reflect.Uint64: return int64(dataVal.Uint()), nil case reflect.Float64: return int64(dataVal.Float()), nil case reflect.Bool: if dataVal.Bool() { return 1, nil } else { return 0, nil } case reflect.String: str := dataVal.String() if str == "" { str = "0" } return strconv.ParseInt(str, 0, 10) default: return 0, errors.New("不支持的类型: " + dataVal.Type().Elem().String()) } } // ToUint64 将any类型的值进行转化为uint64类型 func ToUint64(data any) (uint64, error) { if data == nil { return 0, nil } dataVal := reflect.Indirect(reflect.ValueOf(data)) dataKind := GroupValueKind(dataVal) switch dataKind { case reflect.Int64: return uint64(dataVal.Int()), nil case reflect.Uint64: return dataVal.Uint(), nil case reflect.Float64: return uint64(dataVal.Float()), nil case reflect.Bool: if dataVal.Bool() { return 1, nil } else { return 0, nil } case reflect.String: str := dataVal.String() if str == "" { str = "0" } return strconv.ParseUint(str, 0, 10) default: return 0, errors.New("不支持的类型: " + dataVal.Type().Elem().String()) } } // ToBool 将any类型的值进行转化为bool类型 func ToBool(data any) (bool, error) { if data == nil { return false, nil } dataVal := reflect.Indirect(reflect.ValueOf(data)) dataKind := GroupValueKind(dataVal) switch dataKind { case reflect.Bool: return dataVal.Bool(), nil case reflect.Int64: return dataVal.Int() != 0, nil case reflect.Uint64: return dataVal.Uint() != 0, nil case reflect.Float64: return dataVal.Float() != 0, nil case reflect.String: if dataVal.String() == "" { return false, nil } else { return strconv.ParseBool(dataVal.String()) } default: return false, errors.New("不支持的类型: " + dataVal.Type().Elem().String()) } } // ToFloat64 将any类型的值进行转化为float64类型 func ToFloat64(data any) (float64, error) { if data == nil { return 0, nil } dataVal := reflect.Indirect(reflect.ValueOf(data)) dataKind := GroupValueKind(dataVal) switch dataKind { case reflect.Int64: return float64(dataVal.Int()), nil case reflect.Uint64: return float64(dataVal.Uint()), nil case reflect.Float64: return dataVal.Float(), nil case reflect.Bool: if dataVal.Bool() { return 1, nil } else { return 0, nil } case reflect.String: str := dataVal.String() if str == "" { str = "0" } return strconv.ParseFloat(str, 10) default: return 0, errors.New("不支持的类型: " + dataVal.Type().Elem().String()) } } func Zero[T any]() T { var zeroT T zeroAnyValue := reflect.ValueOf(zeroT) zeroAny := ZeroValueToAny(zeroAnyValue) if zeroAny == nil { return zeroT } return zeroAny.(T) } func ZeroValueToAny(v reflect.Value) any { if v.Kind() == reflect.Invalid { return nil } zeroValue := reflect.New(v.Type()).Elem() if zeroValue.Kind() != reflect.Pointer { zero(&zeroValue) return zeroValue.Interface() } zeroValue.Set(reflect.New(zeroValue.Type().Elem())) elemValue := PointerValueElem(zeroValue) zero(&elemValue) return zeroValue.Interface() } func zero(v *reflect.Value) { if v.Kind() == reflect.Slice || v.Kind() == reflect.Array { v.Set(reflect.MakeSlice(v.Type(), 0, 0)) } else if v.Kind() == reflect.Map { v.Set(reflect.MakeMap(v.Type())) } else if v.Kind() == reflect.Chan { v.Set(reflect.MakeChan(v.Type(), 0)) } else { v.Set(reflect.New(v.Type()).Elem()) } }