package reflux import ( "encoding/json" "reflect" "git.fsdpf.net/go/reflux/valuex" ) // R 提供了一个统一的接口,用于访问和操作嵌套的结构体字段、切片元素和映射值 type R interface { valuex.Accessor json.Marshaler json.Unmarshaler // Get 通过路径获取嵌套字段的值,返回一个新的 T 实例 // 参数 p 为路径片段,例如 Get("user", "profile", "name") Get(path ...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 } // New 创建一个新的 R 实例 // 参数 v 可以是指针或非指针类型 // - 如果传入指针: 将直接使用该指针,可以修改原始数据 // - 如果传入值: 会自动创建一个深度克隆的指针副本,修改不影响原始数据 // 支持的类型: map、struct、slice、array // 也支持 interface 类型以及部分基础类型(string/bool/float),会自动解析到实际类型 // 返回一个 R 接口实例,可用于访问和操作嵌套的字段、元素和键值对 func New(v any) R { rv, isPtr, err := normalizeInputValue(v) if err != nil { panic(err) } if !rv.IsValid() { panic("rfx: invalid value") } // 递归解引用指针和接口,直到获取实际的值类型 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} }