首页 > 解决方案 > 解组任意结构的列表并将其附加到带有反射的切片

问题描述

我想解组一个 JSON 字符串,该字符串将是一个任意结构的列表(在运行时确定),并将解组后的结构列表附加到提供给函数的切片(类型在运行前未知,但是是列表被解组的同一时间)。

这是我要实现的目标的最小示例(此处的游乐场链接):

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.Append(resVal, data).Interface(), nil
}

func main() {
    results := []Foo{}
    newResults, err := get(results)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%#v\n", newResults)
}

我相信以上应该可行,但我得到:

panic: reflect.Set: value of type *[]main.Foo is not assignable to type main.Foo

标签: goreflection

解决方案


您可以使用AppendSlice来附加由 a 表示的切片的各个元素reflect.Value。请注意,您data表示指向切片的指针,因此您必须执行data.Elem()才能到达切片。

reflect.AppendSlice(resVal, data.Elem()).Interface()

https://play.golang.org/p/xTfoEvgMoh_U


或者您可以使用Append,但您必须data.Elem()手动解包由 表示的切片。

data = data.Elem()
slice := make([]reflect.Value, data.Len())
for i := range slice {
    slice[i] = data.Index(i)
}
reflect.Append(resVal, slice...).Interface()

https://play.golang.org/p/YcDvv24xZoo


推荐阅读