feat: 支持反射设置指针类型字段

- 如果目标字段是指针类型,它会尝试直接赋值(如果类型兼容),或创建一个新指针并递归设置其指向的值。
  - `rfx_example_test.go` 中新增了测试用例,以验证对 `*string` 等指针字段的设置功能。
This commit is contained in:
2025-12-03 10:44:03 +08:00
parent f9e7f8e781
commit cbe079ddcd
3 changed files with 131 additions and 40 deletions

67
util.go
View File

@@ -95,26 +95,69 @@ func cloneSequence(dst, src reflect.Value) {
}
// cloneElement 克隆单个元素,处理 interface 包装的情况
// 对于复杂类型(struct, map, slice, array)进行深度克隆
// 对于复杂类型(struct, map, slice, array)和指针类型进行深度克隆
// 对于基本类型,直接返回原始值
func cloneElement(elem reflect.Value) reflect.Value {
// 解引用以获取实际值
actualElem := elem
for actualElem.Kind() == reflect.Interface || actualElem.Kind() == reflect.Ptr {
if actualElem.IsNil() {
return elem
// 首先检查 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
}
}
actualElem = actualElem.Elem()
// interface 包装的是复杂类型
if needsDeepClone(wrapped.Kind()) {
clonedElem := reflect.New(wrapped.Type()).Elem()
CloneValue(clonedElem, wrapped)
return clonedElem
}
// interface 包装的是基本类型,直接返回
return elem
}
// 如果元素需要递归克隆(struct, map, slice, array)
if actualElem.IsValid() && needsDeepClone(actualElem.Kind()) {
clonedElem := reflect.New(actualElem.Type()).Elem()
CloneValue(clonedElem, actualElem)
// 处理直接的指针类型
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
}