英文:
Go - Append to []interface{} via reflection
问题
没有反射的情况下,可以将多个类型添加到类型为 []interface{} 的列表中。像这样:
package main
import "fmt"
func main() {
var foo []interface{}
foo = append(foo, "Test")
foo = append(foo, "Foo")
foo = append(foo, 10)
fmt.Printf("%v\n", foo)
}
使用反射是否可能实现这一点?我尝试了以下代码,但是出现了一个恐慌错误,提示:"panic: reflect.Set: value of type string is not assignable to type []interface {}"
package main
import (
"fmt"
"reflect"
)
func rf(inf interface{}) {
val := reflect.Indirect(reflect.ValueOf(inf))
field := val.FieldByName("Foo")
rslice := reflect.MakeSlice(reflect.SliceOf(field.Type()), 0, 5)
v := reflect.Indirect(reflect.ValueOf("Test"))
rslice = reflect.Append(rslice, v)
}
func main() {
var s struct {
Foo []interface{}
}
rf(&s)
fmt.Printf("%+v\n", s)
}
英文:
Without reflection it is possible to add multiple types to a list of type []interface{}. Like so:
package main
import "fmt"
func main() {
var foo []interface{}
foo = append(foo, "Test")
foo = append(foo, "Foo")
foo = append(foo, 10)
fmt.Printf("%v\n", foo)
}
Is this possible with reflection? I try the following but I get a panic saying: "panic: reflect.Set: value of type string is not assignable to type []interface {}"
package main
import (
"fmt"
"reflect"
)
func rf(inf interface{}) {
val := reflect.Indirect(reflect.ValueOf(inf))
field := val.FieldByName("Foo")
rslice := reflect.MakeSlice(reflect.SliceOf(field.Type()), 0, 5)
v := reflect.Indirect(reflect.ValueOf("Test"))
rslice = reflect.Append(rslice, v)
}
func main() {
var s struct {
Foo []interface{}
}
rf(&s)
fmt.Printf("%+v\n", s)
}
答案1
得分: 5
Foo
字段已经是[]interface{}
类型,所以SliceOf
创建了一个[][]interface{}
类型,这就是你看到的错误的原因。
移除SliceOf
,然后使用field.Set(rslice)
将新值设置回结构体字段。
func rf(inf interface{}) {
val := reflect.Indirect(reflect.ValueOf(inf))
field := val.FieldByName("Foo")
rslice := reflect.MakeSlice(field.Type(), 0, 5)
v := reflect.Indirect(reflect.ValueOf("Test"))
rslice = reflect.Append(rslice, v)
field.Set(rslice)
}
http://play.golang.org/p/gWK3-cP_MN
英文:
The Foo
field is already of type []interface{}
, so SliceOf
is creating a [][]interface{}
, which is what causes the error you see.
Remove the SliceOf
, and then use field.Set(rslice)
to set the new value back to the struct field.
func rf(inf interface{}) {
val := reflect.Indirect(reflect.ValueOf(inf))
field := val.FieldByName("Foo")
rslice := reflect.MakeSlice(field.Type(), 0, 5)
v := reflect.Indirect(reflect.ValueOf("Test"))
rslice = reflect.Append(rslice, v)
field.Set(rslice)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论