Go通过反射Unmarshal任意结构体列表并追加到同类型切片报错问题
问题原因
- 你通过
reflect.New(resVal.Type())创建的data是指向切片的指针类型(对应示例就是*[]Foo),而reflect.Append的第二个入参要求是切片的元素类型(对应示例是Foo),类型不匹配直接触发panic。 - 你需要的是将反序列化得到的完整切片追加到原切片,应该用
reflect.AppendSlice方法,同时要把指针里存储的实际切片值取出来再操作。
修复方案
仅需要修改get函数的返回逻辑:反序列化完成后先通过data.Elem()取出指针指向的实际切片,再调用reflect.AppendSlice完成两个切片的合并。
修复后的完整代码如下:
package main import ( "encoding/json" "fmt" "log" "reflect" ) type Foo struct { Name string } func get(results interface{}) (interface{}, error) { resVal := reflect.ValueOf(results) // 创建对应切片类型的指针,用于反序列化 data := reflect.New(resVal.Type()) err := json.Unmarshal([]byte(`[{"name":"data"},{"name":"test"}]`), data.Interface()) if err != nil { return nil, err } // 取出指针指向的切片,和原切片合并 return reflect.AppendSlice(resVal, data.Elem()).Interface(), nil } func main() { results := []Foo{} newResults, err := get(results) if err != nil { log.Fatal(err) } fmt.Printf("%#v\n", newResults) }
运行后输出结果为:
[]main.Foo{main.Foo{Name:"data"}, main.Foo{Name:"test"}}
内容的提问来源于stack exchange,提问作者dbzuk
相关产品推荐
相关产品推荐

