我很难理解如何在另一个结构中保存自定义结构(在很多其他结构中)。目前我的代码如下所示:
type dogs struct {
bleeh string
blaah string
bluuh string
}
type Stuff struct {
collection *mgo.Collection
//myAnimalStruct what type comes here?
}
func NewStuff(c *mgo.Collection) *Stuff {
return &Stuff{
collection: c
}
}
func getAll(s *Stuff) interface{} {
collection = s.collection
var results []dogs
err := collection.Find(bson.M{}).All(&results)
if err != nil {
panic(err)
}
return results
}
现在,我想在getAll函数中摆脱var results [] dog。相反,我想以某种方式从我的Stuff结构中得到那些[]狗,但我无法弄清楚如何。
这就是我调用此函数的方式:
func getMeDogs(w http.ResponseWriter, r *http.Request) interface{} {
collection = Collection("animals")
s := NewStuff(collection)
return getAll(s)
}
那么我怎么能做s:= NewStuff(集合,狗)之类的东西到我的Stuff结构而不将其声明为Stuff中的狗类型(它可能是任何东西,在另一个函数中它可能是我所知道的所有猫。 ..)?
重点是我想将这个getAll函数重用于其他任何类型,而不是为我的63只动物制作几乎相同的getAll函数。喵。
答案 0 :(得分:3)
您可以在Stuff中存储该类型的原型值,并使用反射创建指向该类型值的指针。
type Stuff struct {
collection *mgo.Collection
v interface{} // the prototype value
}
func NewStuff(c *mgo.Collection, v interface{}) *Stuff {
return &Stuff{
collection: c,
v: v,
}
}
func getAll(s *Stuff) (interface{}, error) {
p := reflect.New(reflect.TypeOf(s.v))
if err := s.collection.Find(bson.M{}).All(p.Interface()); err != nil {
return nil, err
}
return p.Elem().Interface(), nil
}
构建Dog集合:
s := NewStuff(collection, []Dog{})
有些人会说反思很慢。这是真的,但在这种情况下,与执行Find()。All()的成本相比,成本很小。对Find()的调用.All()向数据库服务器发送请求并等待响应。使用Mgo的BSON解码器解压缩来自服务器的响应。 BSON解码器大量使用反射。