From a6a936c07cc57dfdb9a74cf99b6294cb65f1e403 Mon Sep 17 00:00:00 2001 From: what Date: Mon, 8 Dec 2025 11:16:36 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=BC=BA=20map=20=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E8=BD=AC=E6=8D=A2=E7=9A=84=E5=AE=B9=E9=94=99=E8=83=BD?= =?UTF-8?q?=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 优化了所有 map 类型转换方法,采用三层转换策略: 1. 优先使用 cast 库进行类型转换 2. cast 失败后,通过 Keys() 和 Get() 进行自定义转换 3. 转换失败时提供完整的错误信息(包含 cast 错误和自定义转换错误) 优化的方法: - StringMapString() - StringMapStringSlice() - StringMapBool() - StringMapInt() - StringMapInt64() - StringMap() 这使得 struct 类型也能成功转换为 map 类型,增强了类型转换的灵活性。 --- rfx.go | 152 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 129 insertions(+), 23 deletions(-) diff --git a/rfx.go b/rfx.go index 05bc931..f9d370c 100644 --- a/rfx.go +++ b/rfx.go @@ -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)) }