英文:
How to create slice of struct using reflection?
问题
我需要使用反射从接口创建一个结构体切片。
我使用反射是因为在不使用它的情况下,我没有看到其他解决方案。
简要来说,该函数接收接口的可变值。
然后,使用反射创建切片并将其传递给另一个函数。
反射要求类型断言
SliceVal.Interface().(SomeStructType)
但是我不能使用它。
在playground上的代码:http://play.golang.org/p/EcQUfIlkTe
代码:
package main
import (
"fmt"
"reflect"
)
type Model interface {
Hi()
}
type Order struct {
H string
}
func (o Order) Hi() {
fmt.Println("hello")
}
func Full(m []Order) []Order {
o := append(m, Order{H: "Bonjour"})
return o
}
func MakeSlices(models ...Model) {
for _, m := range models {
v := reflect.ValueOf(m)
fmt.Println(v.Type())
sliceType := reflect.SliceOf(v.Type())
emptySlice := reflect.MakeSlice(sliceType, 1, 1)
Full(emptySlice.Interface())
}
}
func main() {
MakeSlices(Order{})
}
英文:
I need to create a slice of struct from its interface with reflection.
I used Reflection because do not see any other solution without using it.
Briefly, the function receives variadic values of Interface.
Then, with reflection creates slice and passes it into another function.
Reflection asks to type assertion
SliceVal.Interface().(SomeStructType)
But, I cannot use it.
Code in playground http://play.golang.org/p/EcQUfIlkTe
The code:
package main
import (
"fmt"
"reflect"
)
type Model interface {
Hi()
}
type Order struct {
H string
}
func (o Order) Hi() {
fmt.Println("hello")
}
func Full(m []Order) []Order{
o := append(m, Order{H:"Bonjour"}
return o
}
func MakeSlices(models ...Model) {
for _, m := range models {
v := reflect.ValueOf(m)
fmt.Println(v.Type())
sliceType := reflect.SliceOf(v.Type())
emptySlice := reflect.MakeSlice(sliceType, 1, 1)
Full(emptySlice.Interface())
}
}
func main() {
MakeSlices(Order{})
}
答案1
得分: 4
你快要成功了。问题在于你不需要将类型断言为结构体类型,而是需要断言为切片类型。
所以,不要使用以下代码:
SliceVal.Interface().(SomeStructType)
而应该使用:
SliceVal.Interface().([]SomeStructType)
在你的具体示例中,只需更改以下一行即可使代码正常工作:
Full(emptySlice.Interface().([]Order))
现在,如果你有多个可能的模型,你可以这样做:
switch s := emptySlice.Interface().(type) {
case []Order:
Full(s)
case []SomeOtherModel:
FullForOtherModel(s)
// 等等
}
英文:
You're almost there. The problem is that you don't need to type-assert to the struct type, but to the slice type.
So instead of
SliceVal.Interface().(SomeStructType)
You should do:
SliceVal.Interface().([]SomeStructType)
And in your concrete example - just changing the following line makes your code work:
Full(emptySlice.Interface().([]Order))
Now, if you have many possible models you can do the following:
switch s := emptySlice.Interface().(type) {
case []Order:
Full(s)
case []SomeOtherModel:
FullForOtherModel(s)
// etc
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论