【问题标题】:Go and custom struct type in another struct转到另一个结构中的自定义结构类型
【发布时间】:2014-09-10 14:59:55
【问题描述】:

我正在努力理解如何将自定义结构保存在另一个结构中(以及许多其他东西)。目前我的代码如下所示:

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 []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 中声明它是狗类型(它可以是任何东西,在另一个函数中,据我所知,它可能是猫。 ..)?

关键是我想将这个 getAll 函数重用于任何其他类型,而不是为我的所有 63 只动物创建几乎相同的 getAll 函数。喵。

【问题讨论】:

    标签: struct go mgo


    【解决方案1】:

    您可以在 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 解码器大量使用反射。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-30
      • 2015-05-24
      • 2022-01-02
      • 2011-04-20
      • 2013-10-17
      • 2020-08-11
      相关资源
      最近更新 更多