我有一个函数期望接收指向未知定义的结构的指针数组。我希望能够创建未知结构的新实例,为其赋值,然后将其附加到给定的数组。
// Someone using this package example:
type Foo Struct {
Val int
Nested []Bar
}
type Bar struct {
Val int
}
func main() {
var foos []*Foo
Mutate(&foos)
// Expect foos[0] to be:
// Foo{Val: 1, Nested: { Bar{Val: 2} } }
}
// My function (no access to definition of Foo)
func Mutate(target any) {
// This is where i am stuck
t := reflect.TypeOf(target).Elem()
// => []*main.Foo
// I have no idea of how to create a new instance
// of main.Foo or even see what fields it has.
}
试试这个代码:
func Mutate(target any) {
// Get reflect.Value for slice.
slice := reflect.ValueOf(target).Elem()
// Create pointer to value. Set a field in the value.
valuet := slice.Type().Elem().Elem()
valuep := reflect.New(valuet)
value := valuep.Elem()
value.FieldByName("Val").SetInt(1)
// Append value pointer to slice set resulting slice
// in target.
slice.Set(reflect.Append(slice, valuep))
}
虽然 Jeremy 的答案是正确的,但结果
foos[0]
是 Foo{Val: 1, Nested: nil }
。通过 Reflect 设置层次结构值可能很棘手,所以我可以建议使用 JSON 吗?
首先生成一个新的
Foo
值并将其附加到切片中:
t := reflect.ValueOf(target).Elem()
foo := reflect.New(t.Type().Elem().Elem())
t.Set(reflect.Append(t, foo))
然后使用 JSON 填写值
Foo{Val:1 Nested:[Bar{Val:2}]}
:
v := `{"Val":1,"Nested":[{"Val":2}]}`
if err := json.Unmarshal([]byte(v), foo.Interface()); err != nil {
log.Fatal(err) // do some reasonable error handling here
}
在 Go Playground 查看结果。