feat: 完善 normalizeInputValue 支持 valuex.Accessor 并优化代码
- 在 valuex.Accessor 接口中添加 Raw() 方法 - normalizeInputValue 支持 valuex.Accessor 和 []valuex.Accessor 类型 - 提取 normalizeAccessorSlice 泛型函数消除重复代码 - 使用 switch 语句替代 if-else 链提高可读性 - 添加相关测试用例确保功能正确性
This commit is contained in:
92
util.go
92
util.go
@@ -6,6 +6,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"git.fsdpf.net/go/reflux/valuex"
|
||||
)
|
||||
|
||||
// DeepClone 深度克隆一个 reflect.Value
|
||||
@@ -335,54 +337,68 @@ func tryMapFieldKey(m reflect.Value, key string) reflect.Value {
|
||||
return reflect.Value{}
|
||||
}
|
||||
|
||||
// normalizeAccessorSlice 规范化 Accessor 切片为 reflect.Value
|
||||
// 这个辅助函数用于处理 []R 和 []valuex.Accessor 的共同逻辑
|
||||
func normalizeAccessorSlice[T valuex.Accessor](slice []T, typeName string) (reflect.Value, bool, error) {
|
||||
var elemType reflect.Type
|
||||
for _, it := range slice {
|
||||
// 检查是否为 nil (通过 any 转换检查)
|
||||
if any(it) == nil {
|
||||
continue
|
||||
}
|
||||
val := it.Raw()
|
||||
if val.IsValid() {
|
||||
elemType = val.Type()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 如果所有元素都是 nil 或无效,返回 nil
|
||||
if elemType == nil {
|
||||
return reflect.ValueOf(nil), false, nil
|
||||
}
|
||||
|
||||
// 创建底层切片
|
||||
count := len(slice)
|
||||
rv := reflect.MakeSlice(reflect.SliceOf(elemType), count, count)
|
||||
for i, it := range slice {
|
||||
if any(it) == nil {
|
||||
continue
|
||||
}
|
||||
val := it.Raw()
|
||||
if !val.IsValid() {
|
||||
continue
|
||||
}
|
||||
if !val.Type().AssignableTo(elemType) {
|
||||
return rv, true, fmt.Errorf("rfx: []%s element type mismatch at index %d: got %s, want %s", typeName, i, val.Type(), elemType)
|
||||
}
|
||||
rv.Index(i).Set(val)
|
||||
}
|
||||
|
||||
return rv, true, nil
|
||||
}
|
||||
|
||||
// normalizeInputValue 规范化传入的任意值为 reflect.Value
|
||||
// 返回对应的 reflect.Value 以及是否应被视为指针(isPtr)
|
||||
func normalizeInputValue(v any) (reflect.Value, bool, error) {
|
||||
var rv reflect.Value
|
||||
var isPtr bool
|
||||
|
||||
if vv, ok := v.(R); ok {
|
||||
switch vv := v.(type) {
|
||||
case R:
|
||||
isPtr = true
|
||||
rv = vv.Raw()
|
||||
} else if vv, ok := v.([]R); ok {
|
||||
// 支持直接传入 []R,自动转换为底层切片
|
||||
var elemType reflect.Type
|
||||
for _, it := range vv {
|
||||
if it == nil {
|
||||
continue
|
||||
}
|
||||
val := it.Raw()
|
||||
if val.IsValid() {
|
||||
elemType = val.Type()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 如果所有元素都是 nil 或无效,退回到通用处理
|
||||
if elemType == nil {
|
||||
rv = reflect.ValueOf(nil)
|
||||
} else {
|
||||
isPtr = true
|
||||
count := len(vv)
|
||||
rv = reflect.MakeSlice(reflect.SliceOf(elemType), count, count)
|
||||
for i, it := range vv {
|
||||
if it == nil {
|
||||
continue
|
||||
}
|
||||
val := it.Raw()
|
||||
if !val.IsValid() {
|
||||
continue
|
||||
}
|
||||
if !val.Type().AssignableTo(elemType) {
|
||||
return rv, isPtr, fmt.Errorf("rfx: []R element type mismatch at index %d: got %s, want %s", i, val.Type(), elemType)
|
||||
}
|
||||
rv.Index(i).Set(val)
|
||||
}
|
||||
}
|
||||
} else if vv, ok := v.(reflect.Value); ok {
|
||||
case valuex.Accessor:
|
||||
isPtr = true
|
||||
rv = vv.Raw()
|
||||
case []valuex.Accessor:
|
||||
return normalizeAccessorSlice(vv, "valuex.Accessor")
|
||||
case []R:
|
||||
return normalizeAccessorSlice(vv, "R")
|
||||
case reflect.Value:
|
||||
// 支持直接传入 reflect.Value,避免重复封装
|
||||
rv = vv
|
||||
} else {
|
||||
default:
|
||||
rv = reflect.ValueOf(v)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user