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

huangapple go评论75阅读模式
英文:

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

问题

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

//如果查询参数为nil,则给它一个空查询
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 {},而不是 []mydbs.CS_Group
如何将返回值转换为我的结构体?

英文:
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

得分: 3

你无法自动地在两种不同类型的切片之间进行转换,包括[]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))
}
英文:

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

答案2

得分: -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返回的类型与你的结构字段的类型匹配。你可能需要在bson.M值类型上添加一些类型转换和类型切换。

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

func GetFromDB(tableName string, m *bson.M, result interface{}) error {
	var (
		__session *mgo.Session = getSession()
	)
	//如果查询参数为nil,则给它一个空查询
	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{}?

英文:

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{}?

huangapple
  • 本文由 发表于 2014年10月1日 19:28:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/26140317.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定