How do I convert from a slice of interface{} to a slice of my struct type in Go? [duplicate]

南楼画角 提交于 2021-02-16 15:34:14

问题


func GetFromDB(tableName string, m *bson.M) interface{} {
    var (
        __session *mgo.Session = getSession()
    )

    //if the query arg is nil. give it the null query
    if m == nil {
        m = &bson.M{}
    }

    __result := []interface{}{}
    __cs_Group := __session.DB(T_dbName).C(tableName)
    __cs_Group.Find(m).All(&__result)

    return __result
}

call

GetFromDB(T_cs_GroupName, &bson.M{"Name": "Alex"}).([]CS_Group)

runtime will give me panic:

panic: interface conversion: interface is []interface {}, not []mydbs.CS_Group

how convert the return value to my struct?


回答1:


You need to convert the entire hierarchy of objects:

rawResult := GetFromDB(T_cs_GroupName, &bson.M{"Name": "Alex"}).([]interface{})
var result []CS_Group
for _, m := range rawResult {
   result = append(result, 
       CS_Group{
         SomeField: m["somefield"].(typeOfSomeField),
         AnotherField: m["anotherfield"].(typeOfAnotherField),
       })
}

This code is for the simple case where the type returned from mgo matches the type of your struct fields. You may need to sprinkle in some type conversions and type switches on the bson.M value types.

An alternate approach is to take advantage of mgo's decoder by passing the output slice as an argument:

func GetFromDB(tableName string, m *bson.M, result interface{}) error {
    var (
        __session *mgo.Session = getSession()
    )
    //if the query arg is nil. give it the null query
    if m == nil {
        m = &bson.M{}
    }
    __result := []interface{}{}
    __cs_Group := __session.DB(T_dbName).C(tableName)
    return __cs_Group.Find(m).All(result)
}

With this change, you can fetch directly to your type:

 var result []CS_Group
 err := GetFromDB(T_cs_GroupName, bson.M{"Name": "Alex"}, &result)

See also: FAQ: Can I convert a []T to an []interface{}?




回答2:


You can't automatically convert between a slice of two different types – that includes []interface{} to []CS_Group. In every case, you need to convert each element individually:

s := GetFromDB(T_cs_GroupName, &bson.M{"Name": "Alex"}).([]interface{})
g := make([]CS_Group, 0, len(s))
for _, i := range s {
    g = append(g, i.(CS_Group))
}


来源:https://stackoverflow.com/questions/26140317/how-do-i-convert-from-a-slice-of-interface-to-a-slice-of-my-struct-type-in-go

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!