如何从Go的一个切片转换为我的结构类型切片?

时间:2014-10-01 11:28:14

标签: interface go

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
}

致电

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

运行时会让我感到恐慌:

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

如何将返回值转换为我的结构?

2 个答案:

答案 0 :(得分:2)

您无法在两种不同类型的切片之间自动转换 - 包括[]interface{}[]CS_Group。在每种情况下,您都需要单独转换每个元素:

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))
}

答案 1 :(得分:-1)

您需要转换整个对象层次结构:

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),
       })
}

此代码适用于从mgo返回的类型与struct字段的类型匹配的简单情况。您可能需要在某些类型的转换中进行转换,并在bson.M值类型上键入开关。

另一种方法是通过传递输出切片作为参数来利用mgo的解码器:

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)
}

通过此更改,您可以直接获取您的类型:

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

另请参阅:FAQ: Can I convert a []T to an []interface{}?