feat: 优化 setValue 方法支持 nil 值处理

改进 setValue 方法在处理 nil 值时的行为:
- 对于可空类型(指针、接口、切片、map 等)设置为零值而非失败
- 对于基础类型(int、string、bool 等)继续执行 cast 转换逻辑
- 修复 val 无效时调用 val.Type() 的潜在空指针问题
This commit is contained in:
what 2025-12-09 14:53:36 +08:00
parent 2b7ac003a8
commit 6e3593f188

22
rfx.go
View File

@ -272,17 +272,26 @@ func (r *rfx) setValue(field reflect.Value, v any) bool {
return false return false
} }
if !val.IsValid() { targetType := field.Type()
return false
}
if !val.IsValid() {
// 如果值无效(通常是 nil 的情况)
// 对于可以为 nil 的类型,直接设置零值
switch targetType.Kind() {
case reflect.Ptr, reflect.Interface, reflect.Slice, reflect.Map, reflect.Chan, reflect.Func:
field.Set(reflect.Zero(targetType))
return true
default:
// 对于基础类型,继续使用后面的 cast 转换逻辑
// 不提前返回 false
}
} else {
// 如果 val 有效,进行正常的类型处理
// 统一解开最外层的 interface 包装,便于后续根据底层实际类型做处理 // 统一解开最外层的 interface 包装,便于后续根据底层实际类型做处理
for val.Kind() == reflect.Interface && !val.IsNil() { for val.Kind() == reflect.Interface && !val.IsNil() {
val = val.Elem() val = val.Elem()
} }
targetType := field.Type()
// 尝试直接赋值(类型完全匹配) // 尝试直接赋值(类型完全匹配)
if val.Type().AssignableTo(targetType) { if val.Type().AssignableTo(targetType) {
field.Set(val) field.Set(val)
@ -366,6 +375,7 @@ func (r *rfx) setValue(field reflect.Value, v any) bool {
return true return true
} }
}
// 优先使用 cast 进行智能类型转换 // 优先使用 cast 进行智能类型转换
// 这样可以处理 string <-> number, number <-> bool 等常见转换 // 这样可以处理 string <-> number, number <-> bool 等常见转换
@ -406,7 +416,7 @@ func (r *rfx) setValue(field reflect.Value, v any) bool {
if err != nil { if err != nil {
// 如果 cast 失败,尝试标准的反射类型转换作为后备 // 如果 cast 失败,尝试标准的反射类型转换作为后备
if val.Type().ConvertibleTo(field.Type()) { if val.IsValid() && val.Type().ConvertibleTo(field.Type()) {
field.Set(val.Convert(field.Type())) field.Set(val.Convert(field.Type()))
return true return true
} }