Bläddra i källkod

添加反射函数

yjp 7 månader sedan
förälder
incheckning
d38da9c62a
1 ändrade filer med 262 tillägg och 0 borttagningar
  1. 262 0
      reflectutils/reflectutils.go

+ 262 - 0
reflectutils/reflectutils.go

@@ -0,0 +1,262 @@
+package reflectutils
+
+import (
+	"errors"
+	"fmt"
+	"reflect"
+	"strconv"
+)
+
+// GroupValueKind 将反射的Kind值进行聚集
+func GroupValueKind(val reflect.Value) reflect.Kind {
+	kind := val.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
+	}
+}
+
+// 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")
+	}
+
+	dataVal := reflect.Indirect(reflect.ValueOf(data))
+	dataKind := GroupValueKind(dataVal)
+
+	switch dataKind {
+	case reflect.String:
+		val.SetString(dataVal.String())
+	case reflect.Bool:
+		if dataVal.Bool() {
+			val.SetString("1")
+		} else {
+			val.SetString("0")
+		}
+	case reflect.Int64:
+		val.SetString(strconv.FormatInt(dataVal.Int(), 10))
+	case reflect.Uint64:
+		val.SetString(strconv.FormatUint(dataVal.Uint(), 10))
+	case reflect.Float64:
+		val.SetString(strconv.FormatFloat(dataVal.Float(), 'f', -1, 64))
+	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)
+		}
+
+		val.SetString(string(uints))
+	default:
+		return errors.New("不支持的类型: " + dataVal.Type().Elem().String())
+	}
+
+	return nil
+}
+
+// AssignIntValue 将any类型的值进行转化,赋值给int类型的reflect.Value
+func AssignIntValue(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")
+	}
+
+	dataVal := reflect.Indirect(reflect.ValueOf(data))
+	dataKind := GroupValueKind(dataVal)
+
+	switch dataKind {
+	case reflect.Int64:
+		val.SetInt(dataVal.Int())
+	case reflect.Uint64:
+		val.SetInt(int64(dataVal.Uint()))
+	case reflect.Float64:
+		val.SetInt(int64(dataVal.Float()))
+	case reflect.Bool:
+		if dataVal.Bool() {
+			val.SetInt(1)
+		} else {
+			val.SetInt(0)
+		}
+	case reflect.String:
+		str := dataVal.String()
+		if str == "" {
+			str = "0"
+		}
+
+		i, err := strconv.ParseInt(str, 0, val.Type().Bits())
+		if err != nil {
+			return errors.New("不支持的类型: " + dataVal.Type().Elem().String())
+		}
+
+		val.SetInt(i)
+	default:
+		return errors.New("不支持的类型: " + dataVal.Type().Elem().String())
+	}
+
+	return nil
+}
+
+// AssignUintValue 将any类型的值进行转化,赋值给uint类型的reflect.Value
+func AssignUintValue(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")
+	}
+
+	dataVal := reflect.Indirect(reflect.ValueOf(data))
+	dataKind := GroupValueKind(dataVal)
+
+	switch dataKind {
+	case reflect.Int64:
+		i := dataVal.Int()
+		if i < 0 {
+			return fmt.Errorf("数值溢出: %d", i)
+		}
+
+		val.SetUint(uint64(i))
+	case reflect.Uint64:
+		val.SetUint(dataVal.Uint())
+	case reflect.Float64:
+		f := dataVal.Float()
+		if f < 0 {
+			return fmt.Errorf("数值溢出: %f", f)
+		}
+
+		val.SetUint(uint64(f))
+	case reflect.Bool:
+		if dataVal.Bool() {
+			val.SetUint(1)
+		} else {
+			val.SetUint(0)
+		}
+	case reflect.String:
+		str := dataVal.String()
+		if str == "" {
+			str = "0"
+		}
+
+		i, err := strconv.ParseUint(str, 0, val.Type().Bits())
+		if err != nil {
+			return err
+		}
+
+		val.SetUint(i)
+	default:
+		return errors.New("不支持的类型: " + dataVal.Type().Elem().String())
+	}
+
+	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")
+	}
+
+	dataVal := reflect.Indirect(reflect.ValueOf(data))
+	dataKind := GroupValueKind(dataVal)
+
+	switch dataKind {
+	case reflect.Bool:
+		val.SetBool(dataVal.Bool())
+	case reflect.Int64:
+		val.SetBool(dataVal.Int() != 0)
+	case reflect.Uint64:
+		val.SetBool(dataVal.Uint() != 0)
+	case reflect.Float64:
+		val.SetBool(dataVal.Float() != 0)
+	case reflect.String:
+		if dataVal.String() == "" {
+			val.SetBool(false)
+		} else {
+			b, err := strconv.ParseBool(dataVal.String())
+			if err != nil {
+				return err
+			}
+
+			val.SetBool(b)
+		}
+	default:
+		return errors.New("不支持的类型: " + dataVal.Type().Elem().String())
+	}
+
+	return nil
+}
+
+// AssignFloatValue 将any类型的值进行转化,赋值给float类型的reflect.Value
+func AssignFloatValue(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")
+	}
+
+	dataVal := reflect.Indirect(reflect.ValueOf(data))
+	dataKind := GroupValueKind(dataVal)
+
+	switch dataKind {
+	case reflect.Int64:
+		val.SetFloat(float64(dataVal.Int()))
+	case reflect.Uint64:
+		val.SetFloat(float64(dataVal.Uint()))
+	case reflect.Float64:
+		val.SetFloat(dataVal.Float())
+	case reflect.Bool:
+		if dataVal.Bool() {
+			val.SetFloat(1)
+		} else {
+			val.SetFloat(0)
+		}
+	case reflect.String:
+		str := dataVal.String()
+		if str == "" {
+			str = "0"
+		}
+
+		f, err := strconv.ParseFloat(str, val.Type().Bits())
+		if err == nil {
+			return err
+		}
+
+		val.SetFloat(f)
+	default:
+		return errors.New("不支持的类型: " + dataVal.Type().Elem().String())
+	}
+
+	return nil
+}