yjp 6 месяцев назад
Родитель
Сommit
1658c9c549
2 измененных файлов с 69 добавлено и 11 удалено
  1. 28 0
      reflectutils/type.go
  2. 41 11
      reflectutils/value.go

+ 28 - 0
reflectutils/type.go

@@ -71,3 +71,31 @@ func IsTypeTime(t reflect.Type) bool {
 func IsTypeTimePointer(t reflect.Type) bool {
 	return t.Kind() == reflect.Pointer && IsTypeTime(t.Elem())
 }
+
+func ZeroType(t reflect.Type) reflect.Value {
+	zeroValue := reflect.New(t).Elem()
+	if zeroValue.Kind() != reflect.Pointer {
+		zero(&zeroValue)
+		return zeroValue
+	}
+
+	zeroValue.Set(reflect.New(zeroValue.Type().Elem()))
+	elemValue := PointerValueElem(zeroValue)
+	zero(&elemValue)
+
+	return zeroValue
+}
+
+func ZeroTypeToAny(t reflect.Type) any {
+	zeroValue := reflect.New(t).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()
+}

+ 41 - 11
reflectutils/value.go

@@ -354,18 +354,48 @@ func ToFloat64(data any) (float64, error) {
 	}
 }
 
-func Zero(v *reflect.Value) {
-	if v.Kind() == reflect.Ptr {
-		elemValue := PointerValueElem(*v)
-		zero(&elemValue)
-		v.Set(elemValue.Addr())
-	} else 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 {
-		v.Set(reflect.New(v.Type()).Elem())
+func Zero[T any]() any {
+	var zeroAny T
+
+	zeroValue := reflect.New(reflect.TypeOf(zeroAny)).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 ZeroValue(v reflect.Value) reflect.Value {
+	zeroValue := reflect.New(v.Type()).Elem()
+	if zeroValue.Kind() != reflect.Pointer {
+		zero(&zeroValue)
+		return zeroValue
+	}
+
+	zeroValue.Set(reflect.New(zeroValue.Type().Elem()))
+	elemValue := PointerValueElem(zeroValue)
+	zero(&elemValue)
+
+	return zeroValue
+}
+
+func ZeroValueToAny(v reflect.Value) any {
+	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) {