feat: 支持反射设置指针类型字段

- 如果目标字段是指针类型,它会尝试直接赋值(如果类型兼容),或创建一个新指针并递归设置其指向的值。
  - `rfx_example_test.go` 中新增了测试用例,以验证对 `*string` 等指针字段的设置功能。
This commit is contained in:
2025-12-03 10:44:03 +08:00
parent f9e7f8e781
commit cbe079ddcd
3 changed files with 131 additions and 40 deletions

View File

@@ -6,22 +6,27 @@ import "fmt"
// 传入指针时,修改会影响原始数据
func ExampleNew_withPointer() {
type Person struct {
Name string
Age int
Name string
Age int
Email *string
}
person := Person{Name: "Alice", Age: 30}
email := "alice@example.com"
person := Person{Name: "Alice", Age: 30, Email: &email}
// 传入指针 - 修改会影响原始数据
rfx := New(&person)
rfx.Set("Name", "Bob")
rfx.Set("Age", 35)
// 原始数据已被修改
fmt.Printf("Name: %s, Age: %d\n", person.Name, person.Age)
// 对于指针字段,Set 会设置指针指向的值
rfx.Set("Email", "bob@example.com")
// 原始数据已被修改(包括指针字段指向的值)
fmt.Printf("Name: %s, Age: %d, Email: %s\n", person.Name, person.Age, *person.Email)
// Output:
// Name: Bob, Age: 35
// Name: Bob, Age: 35, Email: bob@example.com
}
// ExampleNew_withPointer_map 演示传入 map 指针
@@ -63,21 +68,27 @@ func ExampleNew_withPointer_slice() {
// 传入值时,会创建深度克隆,修改不会影响原始数据
func ExampleNew_withValue() {
type Person struct {
Name string
Age int
Name string
Age int
Email *string
}
person := Person{Name: "Alice", Age: 30}
email := "alice@example.com"
person := Person{Name: "Alice", Age: 30, Email: &email}
// 传入值 - 会创建深度克隆,修改不会影响原始数据
// 传入值 - 会创建深度克隆,修改不会影响原始数据(包括指针字段)
rfx := New(person)
fmt.Printf("After New: %+v\n", rfx.Any())
// 显示克隆后的数据(指针字段会显示实际值)
clonedPerson := rfx.Any().(Person)
fmt.Printf("After New - Name: %s, Age: %d, Email: %s\n",
clonedPerson.Name, clonedPerson.Age, *clonedPerson.Email)
rfx.Set("Name", "Bob")
rfx.Set("Age", 35)
// 原始数据未被修改
fmt.Printf("Original - Name: %s, Age: %d\n", person.Name, person.Age)
fmt.Printf("Original - Name: %s, Age: %d, Email: %s\n", person.Name, person.Age, *person.Email)
// rfx 内部的数据已修改
fmt.Printf("Clone - Name: %s, Age: %d\n",
@@ -85,38 +96,54 @@ func ExampleNew_withValue() {
rfx.Get("Age").Int())
// Output:
// After New: {Name:Alice Age:30}
// Original - Name: Alice, Age: 30
// After New - Name: Alice, Age: 30, Email: alice@example.com
// Original - Name: Alice, Age: 30, Email: alice@example.com
// Clone - Name: Bob, Age: 35
}
// ExampleNew_withValue_map 演示传入 map 值
// 传入值时会创建深度克隆,即使 map 是引用类型
func ExampleNew_withValue_map() {
host := "localhost"
port := 8080
config := map[string]any{
"host": "localhost",
"port": 8080,
"host": &host,
"port": &port,
"enabled": true,
}
// 传入 map 值 - 会创建深度克隆
// 传入 map 值 - 会创建深度克隆(包括指针值)
rfx := New(config)
fmt.Printf("After New: %v\n", rfx.Any())
rfx.Set("host", "127.0.0.1")
rfx.Set("port", 9090)
// 显示克隆后的数据(指针值会显示实际内容)
clonedConfig := rfx.Any().(map[string]any)
fmt.Printf("After New - Host: %s, Port: %d, Enabled: %t\n",
*clonedConfig["host"].(*string),
*clonedConfig["port"].(*int),
clonedConfig["enabled"].(bool))
// 修改克隆的数据
newHost := "127.0.0.1"
newPort := 9090
clonedConfig["host"] = &newHost
clonedConfig["port"] = &newPort
// 原始 map 未被修改
fmt.Printf("Original - Host: %s, Port: %v\n", config["host"], config["port"])
fmt.Printf("Original - Host: %s, Port: %d, Enabled: %t\n",
*config["host"].(*string),
*config["port"].(*int),
config["enabled"].(bool))
// rfx 内部的数据已修改
fmt.Printf("Clone - Host: %s, Port: %v\n",
rfx.Get("host").String(),
rfx.Get("port").Int())
// 克隆的数据已修改
fmt.Printf("Clone - Host: %s, Port: %d, Enabled: %t\n",
*clonedConfig["host"].(*string),
*clonedConfig["port"].(*int),
clonedConfig["enabled"].(bool))
// Output:
// After New: map[host:localhost port:8080]
// Original - Host: localhost, Port: 8080
// Clone - Host: 127.0.0.1, Port: 9090
// After New - Host: localhost, Port: 8080, Enabled: true
// Original - Host: localhost, Port: 8080, Enabled: true
// Clone - Host: 127.0.0.1, Port: 9090, Enabled: true
}
// ExampleNew_withValue_slice 演示传入 slice 值