猿问

如何向切片反射添加元素?

我正在学习Go,我正在做一些反思。我陷入了这样的情况:


我想创建一个slice传递struct给函数的interface{}

然后我想将新元素附加到这个切片

这是一个带有代码示例的游乐场。


package main


import (

    "fmt"

    "reflect"

)


type A struct{ Name string }


func main() {

    bbb(A{})

}


func aaa(v interface{}) {

    sl := reflect.ValueOf(v).Elem()

    typeOfT := sl.Type()


    ptr := reflect.New(typeOfT).Interface()

    s := reflect.ValueOf(ptr).Elem()

    sl.Set(reflect.Append(sl, s))


    ptr = reflect.New(typeOfT).Interface()

    s = reflect.ValueOf(ptr).Elem()

    sl.Set(reflect.Append(sl, s))

}


func bbb(v interface{}) {

    myType := reflect.TypeOf(v)

    models := reflect.Zero(reflect.SliceOf(myType)).Interface()

    aaa(&models)


    fmt.Println(models)

}

错误: panic: reflect: call of reflect.Append on interface Value


有没有办法让它工作?注意:我想参考。


解决方案:


这是我设法做的:操场


天涯尽头无女友
浏览 224回答 2
2回答

蓝山帝景

问题出reflect.Zero在我创建 slie 的reflect.New时候。在这里,您有完整的工作示例。https://play.golang.org/p/3mIEFqMxk-package mainimport (&nbsp; &nbsp; "encoding/json"&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "reflect")type A struct {&nbsp; &nbsp; Name string `column:"email"`}func main() {&nbsp; &nbsp; bbb(&A{})}func aaa(v interface{}) {&nbsp; &nbsp; t := reflect.TypeOf(v)&nbsp; &nbsp; if t.Kind() == reflect.Ptr {&nbsp; &nbsp; &nbsp; &nbsp; t = t.Elem()&nbsp; &nbsp; }&nbsp; &nbsp; if t.Kind() == reflect.Slice {&nbsp; &nbsp; &nbsp; &nbsp; t = t.Elem()&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; panic("Input param is not a slice")&nbsp; &nbsp; }&nbsp; &nbsp; sl := reflect.ValueOf(v)&nbsp; &nbsp; if t.Kind() == reflect.Ptr {&nbsp; &nbsp; &nbsp; &nbsp; sl = sl.Elem()&nbsp; &nbsp; }&nbsp; &nbsp; st := sl.Type()&nbsp; &nbsp; fmt.Printf("Slice Type %s:\n", st)&nbsp; &nbsp; sliceType := st.Elem()&nbsp; &nbsp; if sliceType.Kind() == reflect.Ptr {&nbsp; &nbsp; &nbsp; &nbsp; sliceType = sliceType.Elem()&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Printf("Slice Elem Type %v:\n", sliceType)&nbsp; &nbsp; for i := 0; i < 5; i++ {&nbsp; &nbsp; &nbsp; &nbsp; newitem := reflect.New(sliceType)&nbsp; &nbsp; &nbsp; &nbsp; newitem.Elem().FieldByName("Name").SetString(fmt.Sprintf("Grzes %d", i))&nbsp; &nbsp; &nbsp; &nbsp; s := newitem.Elem()&nbsp; &nbsp; &nbsp; &nbsp; for i := 0; i < s.NumField(); i++ {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; col := s.Type().Field(i).Tag.Get("column")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(col, s.Field(i).Addr().Interface())&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; sl.Set(reflect.Append(sl, newitem))&nbsp; &nbsp; }}func bbb(v interface{}) {&nbsp; &nbsp; t := reflect.TypeOf(v)&nbsp; &nbsp; if t.Kind() == reflect.Ptr {&nbsp; &nbsp; &nbsp; &nbsp; t = t.Elem()&nbsp; &nbsp; }&nbsp; &nbsp; if t.Kind() != reflect.Struct {&nbsp; &nbsp; &nbsp; &nbsp; panic("Input param is not a struct")&nbsp; &nbsp; }&nbsp; &nbsp; models := reflect.New(reflect.SliceOf(reflect.TypeOf(v))).Interface()&nbsp; &nbsp; aaa(models)&nbsp; &nbsp; fmt.Println(models)&nbsp; &nbsp; b, err := json.Marshal(models)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; panic(err)&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Println(string(b))}

侃侃尔雅

这是做你想做的吗?(游乐场链接)package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "reflect")type A struct{ Name string }func main() {&nbsp; &nbsp; bbb(A{})}func aaa(v interface{}) interface{} {&nbsp; &nbsp; sl := reflect.Indirect(reflect.ValueOf(v))&nbsp; &nbsp; typeOfT := sl.Type().Elem()&nbsp; &nbsp; ptr := reflect.New(typeOfT).Interface()&nbsp; &nbsp; s := reflect.ValueOf(ptr).Elem()&nbsp; &nbsp; return reflect.Append(sl, s)}func bbb(v interface{}) {&nbsp; &nbsp; myType := reflect.TypeOf(v)&nbsp; &nbsp; models := reflect.MakeSlice(reflect.SliceOf(myType), 0, 1).Interface()&nbsp; &nbsp; fmt.Println(aaa(models))}请注意,我正在返回新切片。我认为您需要另一层间接(指向指针的指针)才能在没有返回值的情况下执行此操作,但这是我第一次在 Go 中进行反射,所以我可能会做错事。
随时随地看视频慕课网APP

相关分类

Go
我要回答