feat: 支持嵌套 R 和 valuex.Accessor 对象的路径访问

- 添加 unwrapAccessor 统一处理 Accessor 解引用
- 添加 deref/derefWithAccessor/derefValue 封装重复的解引用逻辑
- getValueByPath 支持穿透 R/Accessor 对象访问嵌套路径
- setNestedValue 支持在 R/Accessor 对象中设置嵌套值
- CloneValue 和 cloneElement 正确克隆 Accessor 底层值
- 支持在 map/struct/slice 中嵌套 R 对象并通过路径访问
- 添加完整测试覆盖 map/struct/slice/深度嵌套等场景
- 减少 38 行重复代码,提高代码可维护性
This commit is contained in:
2025-12-24 16:37:12 +08:00
parent c62b07a119
commit d233fc319b
3 changed files with 265 additions and 38 deletions

30
rfx.go
View File

@@ -77,14 +77,12 @@ func (r *rfx) Append(items ...any) R {
}
target := r.getParentValue()
for target.Kind() == reflect.Ptr || target.Kind() == reflect.Interface {
if target.IsNil() {
panic(ErrAppendNilValue)
}
target = target.Elem()
}
target = deref(target)
if !target.IsValid() || target.Kind() != reflect.Slice {
if !target.IsValid() {
panic(ErrAppendNilValue)
}
if target.Kind() != reflect.Slice {
panic(ErrAppendNotSupported)
}
@@ -106,15 +104,9 @@ func (r *rfx) Append(items ...any) R {
// setNestedValue 递归设置嵌套值,特殊处理 map 中的 struct
func (r *rfx) setNestedValue(current reflect.Value, keys []string, v any) error {
// 解引用指针和接口
for current.Kind() == reflect.Ptr || current.Kind() == reflect.Interface {
if current.IsNil() {
return ErrNilPointerInPath
}
current = current.Elem()
}
current = derefWithAccessor(current)
if !current.IsValid() {
return ErrInvalidValueInPath
return ErrNilPointerInPath
}
// 如果只剩一个键,直接设置
@@ -202,11 +194,9 @@ func (r *rfx) getParentValue(p ...string) reflect.Value {
// setFieldValue 设置字段值的辅助方法
// 返回 error 包含详细的设置失败信息
func (r *rfx) setFieldValue(target reflect.Value, key string, v any) error {
for target.Kind() == reflect.Ptr || target.Kind() == reflect.Interface {
if target.IsNil() {
return ErrTargetNilPointer
}
target = target.Elem()
target = deref(target)
if !target.IsValid() {
return ErrTargetNilPointer
}
switch target.Kind() {