在另一个结构体中使用和自定义结构类型。

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

Go and custom struct type in another struct

问题

我正在努力理解如何在另一个结构体中保存自定义结构体(以及其他很多事情)。目前我的代码看起来是这样的:

type dogs struct {
  bleeh string
  blaah string
  bluuh string
}

type Stuff struct {
  collection      *mgo.Collection
  //myAnimalStruct 这里应该是什么类型?
}

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 []dogs。相反,我想从我的Stuff结构体中获取[]dogs部分,但我无法弄清楚如何做到。

这是我调用这个函数的方式:

func getMeDogs(w http.ResponseWriter, r *http.Request) interface{} {
  collection = Collection("animals")
  s := NewStuff(collection)
  return getAll(s)
}

那么,我如何在Stuff结构体中做类似s := NewStuff(collection, dogs)这样的事情,而不需要在Stuff中将其声明为dogs类型(它可以是任何类型,在另一个函数中可能是cats)?

关键是我想重用这个getAll函数,用于其他类型,而不是为我所有的63种动物编写几乎相同的getAll函数。喵。

英文:

I'm struggling to understand how to save a custom struct in another struct (amongst great many other things). Currently my code looks like this:

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
}

Now, I would like to get rid of that var results []dogs in getAll function. Instead, I would like to get that []dogs bit from my Stuff struct somehow, but I can't figure out how.

this is how I call this function:

func getMeDogs(w http.ResponseWriter, r *http.Request) interface{} {
  collection = Collection("animals")
  s := NewStuff(collection)
  return getAll(s)
}

So how could I do something like s := NewStuff(collection, dogs) to my Stuff struct without declaring it as a dog type in Stuff (it could be anything, in another function it could be cats for all I know...)?

The point is that I want to reuse this getAll function for whatever other types, instead of making nearly identical getAll function for all of my 63 animals. Meow.

答案1

得分: 3

你可以在Stuff中存储类型的原型值,并使用反射创建指向该类型值的指针。

type Stuff struct {
    collection  *mgo.Collection
    v           interface{}   // 类型的原型值
}

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解码器大量使用了反射。

英文:

You can store a prototypical value of the type in Stuff and use reflection to create a pointer to a value of that type.

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
}

To construct a Dog collection:

s := NewStuff(collection, []Dog{})

Some people will say that reflection is slow. That's true, but in this case the cost is small compared to the cost of executing Find().All(). The call to Find().All() sends a request to the database server and waits for the response. The response from the server is unpacked using Mgo's BSON decoder. The BSON decoder makes heavy use of reflection.

huangapple
  • 本文由 发表于 2014年9月10日 22:59:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/25768783.html
匿名

发表评论

匿名网友

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

确定