reflux/reflux.go

180 lines
4.9 KiB
Go

package reflux
import "reflect"
// R 提供了一个统一的接口,用于访问和操作嵌套的结构体字段、切片元素和映射值
type R interface {
// Get 通过路径获取嵌套字段的值,返回一个新的 R 实例
// 参数 p 为路径片段,例如 Get("user", "profile", "name")
Get(p ...string) R
// Scope 类似 Get,但用于创建一个指定路径的作用域视图
// 后续操作将基于这个作用域进行
Scope(p ...string) R
// Set 设置指定路径的值,支持链式调用
// 参数 key 为路径(支持点号分割),v 为要设置的值
// 返回当前 R 实例以支持链式调用
// 示例: rfx.Set("name", "Alice").Set("age", 30)
Set(key string, v any) R
// Append 追加指定路径的值
// 参数 items 为要追加的值
// 返回当前 R 实例以支持链式调用
Append(items ...any) R
// Delete 删除指定路径的值
// 参数 p 为路径片段
// 返回当前 R 实例以支持链式调用
Delete(p ...string) R
// Exists 检查指定路径的值是否存在
// 参数 p 为路径片段
// 返回 true 表示存在,false 表示不存在
Exists(p ...string) bool
// Array 将当前值转换为 R 切片
// 适用于数组或切片类型的值
Array() []R
// Keys 返回当前映射或结构体的所有键名
Keys() []string
// Value 返回底层的 reflect.Value
// 用于需要直接操作反射值的场景
Value() reflect.Value
// Ptr 返回指向当前值的指针
Ptr() any
// Any 将当前值转换为 any 类型
Any() any
// Bool 将当前值转换为 bool 类型
Bool() bool
// Float64 将当前值转换为 float64 类型
Float64() float64
// Float32 将当前值转换为 float32 类型
Float32() float32
// Int64 将当前值转换为 int64 类型
Int64() int64
// Int32 将当前值转换为 int32 类型
Int32() int32
// Int16 将当前值转换为 int16 类型
Int16() int16
// Int8 将当前值转换为 int8 类型
Int8() int8
// Int 将当前值转换为 int 类型
Int() int
// Uint 将当前值转换为 uint 类型
Uint() uint
// Uint64 将当前值转换为 uint64 类型
Uint64() uint64
// Uint32 将当前值转换为 uint32 类型
Uint32() uint32
// Uint16 将当前值转换为 uint16 类型
Uint16() uint16
// Uint8 将当前值转换为 uint8 类型
Uint8() uint8
// String 将当前值转换为 string 类型
String() string
// StringMapString 将当前值转换为 map[string]string 类型
StringMapString() map[string]string
// StringMapStringSlice 将当前值转换为 map[string][]string 类型
StringMapStringSlice() map[string][]string
// StringMapBool 将当前值转换为 map[string]bool 类型
StringMapBool() map[string]bool
// StringMapInt 将当前值转换为 map[string]int 类型
StringMapInt() map[string]int
// StringMapInt64 将当前值转换为 map[string]int64 类型
StringMapInt64() map[string]int64
// StringMap 将当前值转换为 map[string]any 类型
StringMap() map[string]any
// Slice 将当前值转换为 []any 切片
Slice() []any
// BoolSlice 将当前值转换为 []bool 切片
BoolSlice() []bool
// StringSlice 将当前值转换为 []string 切片
StringSlice() []string
// IntSlice 将当前值转换为 []int 切片
IntSlice() []int
}
// New 创建一个新的 R 实例
// 参数 v 可以是指针或非指针类型
// - 如果传入指针: 将直接使用该指针,可以修改原始数据
// - 如果传入值: 会自动创建一个深度克隆的指针副本,修改不影响原始数据
// 支持的类型: map、struct、slice、array
// 也支持 interface 类型以及部分基础类型(string/bool/float),会自动解析到实际类型
// 返回一个 R 接口实例,可用于访问和操作嵌套的字段、元素和键值对
func New(v any) R {
rv := reflect.ValueOf(v)
if !rv.IsValid() {
panic("rfx: invalid value")
}
// 记录原始是否为指针
isPtr := rv.Kind() == reflect.Ptr
// 递归解引用指针和接口,直到获取实际的值类型
actualValue := rv
for actualValue.Kind() == reflect.Ptr || actualValue.Kind() == reflect.Interface {
if actualValue.IsNil() {
panic("rfx: cannot use nil pointer or nil interface")
}
actualValue = actualValue.Elem()
// 如果解引用后的类型是指针,标记为指针模式
if actualValue.Kind() == reflect.Ptr {
isPtr = true
}
}
// 检查最终的实际类型是否为支持的类型
switch actualValue.Kind() {
case reflect.Map,
reflect.Struct,
reflect.Slice,
reflect.Array,
reflect.String,
reflect.Bool,
reflect.Float32,
reflect.Float64:
// 支持的类型
default:
panic("rfx: unsupported type, only map, struct, slice, and array are allowed")
}
// 如果原始传入的不是指针类型,需要进行深度克隆以避免修改原始数据
// 对于引用类型(map, slice)这尤其重要
if !isPtr {
// 使用深度克隆创建一个完全独立的副本
rv = DeepClone(actualValue)
}
return &rfx{value: rv}
}