如何使用反射创建结构体切片?

7

我需要使用反射从接口创建一个结构体切片。

由于没有其他解决方案,因此我使用了反射。

简要来说,该函数接收接口的可变值。

然后,通过反射创建切片并将其传递到另一个函数中。

反射要求类型断言。

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{})
}
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)
// etc
}

谢谢,我很感激这个答案。因为该函数接收可变变量,所以当我不知道要创建哪个结构体切片时,该如何进行类型断言呢? - maksadbek
@user2660766 如果你有很多可能的类型,如何为特定类型调用Full?你可以简单地进行类型切换,并为每个可能的模型调用单独的函数。 - Not_a_Golfer
这只是一个测试用的示例函数。 - maksadbek
@user2660766,请查看我的扩展答案,我已经添加了一个示例,说明如何基于模型路由到多个函数。 - Not_a_Golfer
有没有什么想法可以在不知道结构类型的情况下进行断言?http://stackoverflow.com/questions/40474682/reflect-set-slice-of-structs-value-to-a-struct-without-type-assertion-because - Charney Kaye

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接