You need to enable JavaScript to run this app. Go通过反射Unmarshal任意结构体列表并追加到同类型切片报错问题
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 22:30:03