feat: 完善 New 方法支持指针和值参数,新增 interface 类型支持
- 支持指针模式: New(&data) - 直接修改原始数据
- 支持值模式: New(data) - 创建深度克隆,不影响原始数据
- 新增 interface{} 类型支持,自动解析到实际类型
- 对 map 和 slice 等引用类型也进行完全深度克隆
- 新增 9 个单元测试覆盖指针/值/interface 场景
- 新增 9 个示例测试展示各种用法
- 所有测试通过,保持性能
- 更新 README.md 详细说明指针/值传递的区别
- 新增 interface 类型使用示例
- 新增泛型数据处理使用场景
- 更新注意事项说明
- 使用递归解引用处理 interface 和指针类型
- 利用 DeepClone 确保引用类型的完全独立
- 保持向后兼容,现有代码无需修改
This commit is contained in:
44
reflux.go
44
reflux.go
@@ -119,13 +119,49 @@ type R interface {
|
||||
}
|
||||
|
||||
// New 创建一个新的 R 实例
|
||||
// 参数 v 必须是指针类型,否则会 panic
|
||||
// 参数 v 可以是指针或非指针类型
|
||||
// - 如果传入指针: 将直接使用该指针,可以修改原始数据
|
||||
// - 如果传入值: 会自动创建一个深度克隆的指针副本,修改不影响原始数据
|
||||
// 支持的类型: map、struct、slice、array
|
||||
// 也支持 interface 类型,会自动解析到实际类型
|
||||
// 返回一个 R 接口实例,可用于访问和操作嵌套的字段、元素和键值对
|
||||
func New(v any) R {
|
||||
rv := reflect.ValueOf(v)
|
||||
// 如果传入的不是指针,panic
|
||||
if rv.Kind() != reflect.Ptr {
|
||||
panic("structmap: New() requires a pointer argument")
|
||||
|
||||
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:
|
||||
// 支持的类型
|
||||
default:
|
||||
panic("rfx: unsupported type, only map, struct, slice, and array are allowed")
|
||||
}
|
||||
|
||||
// 如果原始传入的不是指针类型,需要进行深度克隆以避免修改原始数据
|
||||
// 对于引用类型(map, slice)这尤其重要
|
||||
if !isPtr {
|
||||
// 使用深度克隆创建一个完全独立的副本
|
||||
rv = DeepClone(actualValue)
|
||||
}
|
||||
|
||||
return &rfx{value: rv}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user