dtvnbe1428 2014-09-10 14:59
浏览 22
已采纳

转到另一个结构中的自定义结构类型

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条回答 默认 最新

  • doudula1974 2014-09-10 17:33
    关注

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 UE5#if WITH_EDITOR导致打包的功能不可用
  • ¥15 关于#stm32#的问题:CANOpen的PDO同步传输问题
  • ¥20 yolov5自定义Prune报错,如何解决?
  • ¥15 电磁场的matlab仿真
  • ¥15 mars2d在vue3中的引入问题
  • ¥50 h5唤醒支付宝并跳转至向小荷包转账界面
  • ¥15 算法题:数的划分,用记忆化DFS做WA求调
  • ¥15 chatglm-6b应用到django项目中,模型加载失败
  • ¥15 CreateBitmapFromWicBitmap内存释放问题。
  • ¥30 win c++ socket