package reflux import ( "reflect" "strings" "unicode" ) // DeepClone 深度克隆一个 reflect.Value func DeepClone(v reflect.Value) reflect.Value { // 解引用指针和接口以获取实际值 for v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface { if v.IsNil() { return reflect.Value{} } v = v.Elem() } if !v.IsValid() { return reflect.Value{} } // 创建新值的指针以便修改 cloned := reflect.New(v.Type()) CloneValue(cloned.Elem(), v) return cloned } // CloneValue 递归克隆值 func CloneValue(dst, src reflect.Value) { if !src.IsValid() { return } switch src.Kind() { case reflect.Ptr: if src.IsNil() { return } dst.Set(reflect.New(src.Type().Elem())) CloneValue(dst.Elem(), src.Elem()) case reflect.Interface: if src.IsNil() { return } cloned := DeepClone(src.Elem()) if cloned.IsValid() { dst.Set(cloned) } case reflect.Struct: for i := 0; i < src.NumField(); i++ { if dst.Field(i).CanSet() { CloneValue(dst.Field(i), src.Field(i)) } } case reflect.Slice: if src.IsNil() { return } dst.Set(reflect.MakeSlice(src.Type(), src.Len(), src.Cap())) cloneSequence(dst, src) case reflect.Array: cloneSequence(dst, src) case reflect.Map: if src.IsNil() { return } dst.Set(reflect.MakeMap(src.Type())) for _, key := range src.MapKeys() { val := src.MapIndex(key) clonedVal := cloneElement(val) dst.SetMapIndex(key, clonedVal) } default: // 对于基本类型(int, string, bool, float等),直接赋值 if dst.CanSet() { dst.Set(src) } } } // cloneSequence 克隆序列类型(slice/array)的元素 func cloneSequence(dst, src reflect.Value) { for i := 0; i < src.Len(); i++ { elem := src.Index(i) clonedElem := cloneElement(elem) dst.Index(i).Set(clonedElem) } } // cloneElement 克隆单个元素,处理 interface 包装的情况 // 对于复杂类型(struct, map, slice, array)和指针类型进行深度克隆 // 对于基本类型,直接返回原始值 func cloneElement(elem reflect.Value) reflect.Value { // 首先检查 elem 自身是否是 interface if elem.Kind() == reflect.Interface && !elem.IsNil() { // 获取 interface 包装的实际值 wrapped := elem.Elem() // 如果 interface 包装的是指针,需要深度克隆指针 if wrapped.Kind() == reflect.Ptr && !wrapped.IsNil() { // 克隆指针指向的值 pointedValue := wrapped.Elem() if needsDeepClone(pointedValue.Kind()) { // 复杂类型:递归克隆 clonedValue := reflect.New(pointedValue.Type()).Elem() CloneValue(clonedValue, pointedValue) clonedPtr := reflect.New(pointedValue.Type()) clonedPtr.Elem().Set(clonedValue) return clonedPtr } else { // 基本类型:创建新指针 clonedPtr := reflect.New(pointedValue.Type()) clonedPtr.Elem().Set(pointedValue) return clonedPtr } } // interface 包装的是复杂类型 if needsDeepClone(wrapped.Kind()) { clonedElem := reflect.New(wrapped.Type()).Elem() CloneValue(clonedElem, wrapped) return clonedElem } // interface 包装的是基本类型,直接返回 return elem } // 处理直接的指针类型 if elem.Kind() == reflect.Ptr && !elem.IsNil() { pointedValue := elem.Elem() if needsDeepClone(pointedValue.Kind()) { clonedValue := reflect.New(pointedValue.Type()).Elem() CloneValue(clonedValue, pointedValue) clonedPtr := reflect.New(pointedValue.Type()) clonedPtr.Elem().Set(clonedValue) return clonedPtr } else { // 基本类型的指针,创建新指针 clonedPtr := reflect.New(pointedValue.Type()) clonedPtr.Elem().Set(pointedValue) return clonedPtr } } // 处理复杂类型 if needsDeepClone(elem.Kind()) { clonedElem := reflect.New(elem.Type()).Elem() CloneValue(clonedElem, elem) return clonedElem } // 基本类型,直接返回 return elem } // needsDeepClone 判断某个类型是否需要深度克隆 func needsDeepClone(kind reflect.Kind) bool { return kind == reflect.Struct || kind == reflect.Map || kind == reflect.Slice || kind == reflect.Array } // expandPath 展开路径,支持点号分割 // 例如: expandPath("a.b", "c") -> []string{"a", "b", "c"} func expandPath(p ...string) []string { var result []string for _, segment := range p { // 按点号分割 parts := strings.Split(segment, ".") for _, part := range parts { if part != "" { // 忽略空字符串 result = append(result, part) } } } return result } // capitalizeFirst 将字符串首字母转换为大写 // 用于处理 struct 字段名,使其符合 Go 的公开字段命名规范 func capitalizeFirst(s string) string { if s == "" { return s } runes := []rune(s) runes[0] = unicode.ToUpper(runes[0]) return string(runes) } // tryStructField 尝试获取 struct 字段,支持小写字段名自动转大写 // 1. 首先尝试原始字段名 // 2. 如果失败且首字母是小写,尝试首字母大写的版本 func tryStructField(v reflect.Value, fieldName string) reflect.Value { // 首先尝试原始字段名 field := v.FieldByName(fieldName) if field.IsValid() { return field } // 如果字段名首字母是小写,尝试首字母大写 if len(fieldName) > 0 && unicode.IsLower(rune(fieldName[0])) { capitalizedName := capitalizeFirst(fieldName) field = v.FieldByName(capitalizedName) if field.IsValid() { return field } } return reflect.Value{} }