feat: 增强 map 类型转换的容错能力

优化了所有 map 类型转换方法,采用三层转换策略:
1. 优先使用 cast 库进行类型转换
2. cast 失败后,通过 Keys() 和 Get() 进行自定义转换
3. 转换失败时提供完整的错误信息(包含 cast 错误和自定义转换错误)

优化的方法:
- StringMapString()
- StringMapStringSlice()
- StringMapBool()
- StringMapInt()
- StringMapInt64()
- StringMap()

这使得 struct 类型也能成功转换为 map 类型,增强了类型转换的灵活性。
This commit is contained in:
what 2025-12-08 11:16:36 +08:00
parent 9e1bc55a8c
commit a6a936c07c

152
rfx.go
View File

@ -7,6 +7,7 @@ import (
"strconv"
"strings"
"git.fsdpf.net/go/reflux/valuex"
"github.com/spf13/cast"
)
@ -511,11 +512,20 @@ func (r *rfx) Keys() []string {
return nil
}
// Value 返回底层的 reflect.Value
func (r *rfx) Value() reflect.Value {
// Raw 返回底层的 reflect.Value
func (r *rfx) Raw() reflect.Value {
return r.value
}
// Lookup 根据路径查找并返回对应值的访问器
func (r *rfx) Lookup(path string) (valuex.Accessor, bool) {
v := r.Get(path)
if v.Exists() {
return v, true
}
return valuex.Nil, false
}
// Ptr 返回指向当前值的指针
func (r *rfx) Ptr() any {
v := r.value
@ -676,55 +686,151 @@ func (r *rfx) String() string {
// StringMapString 将当前值转换为 map[string]string 类型
func (r *rfx) StringMapString() map[string]string {
result, err := cast.ToStringMapStringE(r.Any())
if err != nil {
panic(fmt.Sprintf("rfx: failed to convert to map[string]string: %v", err))
data := r.Any()
// 首先尝试使用 cast 进行转换
result, err := cast.ToStringMapStringE(data)
if err == nil {
return result
}
// cast 失败后,尝试自定义转换逻辑
defer func() {
if p := recover(); p != nil {
panic(fmt.Sprintf("rfx: failed to convert to map[string]string, cast error: %v, custom conversion error: %v", err, p))
}
}()
result = make(map[string]string)
for _, k := range r.Keys() {
result[k] = r.Get(k).String()
}
return result
}
// StringMapStringSlice 将当前值转换为 map[string][]string 类型
func (r *rfx) StringMapStringSlice() map[string][]string {
result, err := cast.ToStringMapStringSliceE(r.Any())
if err != nil {
panic(fmt.Sprintf("rfx: failed to convert to map[string][]string: %v", err))
data := r.Any()
// 首先尝试使用 cast 进行转换
result, err := cast.ToStringMapStringSliceE(data)
if err == nil {
return result
}
// cast 失败后,尝试自定义转换逻辑
defer func() {
if p := recover(); p != nil {
panic(fmt.Sprintf("rfx: failed to convert to map[string][]string, cast error: %v, custom conversion error: %v", err, p))
}
}()
result = make(map[string][]string)
for _, k := range r.Keys() {
result[k] = r.Get(k).StringSlice()
}
return result
}
// StringMapBool 将当前值转换为 map[string]bool 类型
func (r *rfx) StringMapBool() map[string]bool {
result, err := cast.ToStringMapBoolE(r.Any())
if err != nil {
panic(fmt.Sprintf("rfx: failed to convert to map[string]bool: %v", err))
data := r.Any()
// 首先尝试使用 cast 进行转换
result, err := cast.ToStringMapBoolE(data)
if err == nil {
return result
}
// cast 失败后,尝试自定义转换逻辑
defer func() {
if p := recover(); p != nil {
panic(fmt.Sprintf("rfx: failed to convert to map[string]bool, cast error: %v, custom conversion error: %v", err, p))
}
}()
result = make(map[string]bool)
for _, k := range r.Keys() {
result[k] = r.Get(k).Bool()
}
return result
}
// StringMapInt 将当前值转换为 map[string]int 类型
func (r *rfx) StringMapInt() map[string]int {
result, err := cast.ToStringMapIntE(r.Any())
if err != nil {
panic(fmt.Sprintf("rfx: failed to convert to map[string]int: %v", err))
data := r.Any()
// 首先尝试使用 cast 进行转换
result, err := cast.ToStringMapIntE(data)
if err == nil {
return result
}
// cast 失败后,尝试自定义转换逻辑
defer func() {
if p := recover(); p != nil {
panic(fmt.Sprintf("rfx: failed to convert to map[string]int, cast error: %v, custom conversion error: %v", err, p))
}
}()
result = make(map[string]int)
for _, k := range r.Keys() {
result[k] = r.Get(k).Int()
}
return result
}
// StringMapInt64 将当前值转换为 map[string]int64 类型
func (r *rfx) StringMapInt64() map[string]int64 {
result, err := cast.ToStringMapInt64E(r.Any())
if err != nil {
panic(fmt.Sprintf("rfx: failed to convert to map[string]int64: %v", err))
data := r.Any()
// 首先尝试使用 cast 进行转换
result, err := cast.ToStringMapInt64E(data)
if err == nil {
return result
}
// cast 失败后,尝试自定义转换逻辑
defer func() {
if p := recover(); p != nil {
panic(fmt.Sprintf("rfx: failed to convert to map[string]int64, cast error: %v, custom conversion error: %v", err, p))
}
}()
result = make(map[string]int64)
for _, k := range r.Keys() {
result[k] = r.Get(k).Int64()
}
return result
}
// StringMap 将当前值转换为 map[string]any 类型
func (r *rfx) StringMap() map[string]any {
result, err := cast.ToStringMapE(r.Any())
if err != nil {
panic(fmt.Sprintf("rfx: failed to convert to map[string]any: %v", err))
data := r.Any()
// 首先尝试使用 cast 进行转换
result, err := cast.ToStringMapE(data)
if err == nil {
return result
}
// cast 失败后,尝试自定义转换逻辑
defer func() {
if p := recover(); p != nil {
panic(fmt.Sprintf("rfx: failed to convert to map[string]any, cast error: %v, custom conversion error: %v", err, p))
}
}()
result = make(map[string]any)
for _, k := range r.Keys() {
result[k] = r.Get(k).Any()
}
return result
}
@ -759,7 +865,7 @@ func (r *rfx) Slice() []any {
// BoolSlice 将当前值转换为 []bool 切片
func (r *rfx) BoolSlice() []bool {
result, err := cast.ToBoolSliceE(r.Any())
result, err := cast.ToBoolSliceE(r.Slice())
if err != nil {
panic(fmt.Sprintf("rfx: failed to convert to []bool: %v", err))
}
@ -768,7 +874,7 @@ func (r *rfx) BoolSlice() []bool {
// StringSlice 将当前值转换为 []string 切片
func (r *rfx) StringSlice() []string {
result, err := cast.ToStringSliceE(r.Any())
result, err := cast.ToStringSliceE(r.Slice())
if err != nil {
panic(fmt.Sprintf("rfx: failed to convert to []string: %v", err))
}
@ -777,7 +883,7 @@ func (r *rfx) StringSlice() []string {
// IntSlice 将当前值转换为 []int 切片
func (r *rfx) IntSlice() []int {
result, err := cast.ToIntSliceE(r.Any())
result, err := cast.ToIntSliceE(r.Slice())
if err != nil {
panic(fmt.Sprintf("rfx: failed to convert to []int: %v", err))
}