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:
30
rfx.go
30
rfx.go
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user