如何在range循环中正确使用Go的append函数?

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

How to make Go append work inside a range loop

问题

我有一个函数,它从一个结构体中获取未知数量的输入:

  1. func GetAllXXXByQueryFilters(ctx context.Context, filters ...XXXFilters) ([]XXX, error) {
  2. var allKeys []*datastore.Key
  3. var xxx []XXX
  4. for _, filter := range filters {
  5. query := datastore.NewQuery("XXX")
  6. if filter.Foo != "" {
  7. query = query.Filter("foo =", filter.Foo)
  8. }
  9. if filter.Bar != "" {
  10. query = query.Filter("bar =", filter.Bar)
  11. }
  12. keys, err := models.DSClient().GetAll(ctx, query, &xxx)
  13. if err != nil {
  14. return nil, err
  15. }
  16. allKeys = append(allKeys, keys...) // 在这里解决问题
  17. }
  18. for i, key := range allKeys {
  19. xxx[i].ID = key.ID
  20. }
  21. return xxx, nil
  22. }

问题在于allKeys会覆盖之前的查询结果。我之前通过以下方式解决了这个问题:

  1. keys1, err := models.DSClient().GetAll(ctx, query1, &xxx)
  2. keys2, err := models.DSClient().GetAll(ctx, query2, &xxx)
  3. keys = append(keys1, keys2...)

但是我希望GetAllXXXByQueryFilters函数更加复杂,避免重复的代码,现在我似乎无法找到如何在for _, filter := range filters循环中存储键并在之后将它们全部追加的方法。所以我希望也许有一种更聪明的方法来替代allKeys = append(keys)这一行,以避免覆盖之前的键。

英文:

I have this function which takes an unknown amount of input from a struct:

  1. func GetAllXXXByQueryFilters(ctx context.Context, filters ...XXXFilters) ([]XXX, error) {
  2. var allKeys []*datastore.Key
  3. var xxx []XXX
  4. for _, filter := range filters {
  5. query := datastore.NewQuery("XXX")
  6. if filter.Foo != "" {
  7. query = query.Filter("foo =", filter.Foo)
  8. }
  9. if filter.Bar != "" {
  10. query = query.Filter("bar =", filter.Bar)
  11. }
  12. keys, err := models.DSClient().GetAll(ctx, query, &xxx)
  13. if err != nil {
  14. return nil, err
  15. }
  16. allKeys = append(keys) // PROBLEM HERE
  17. }
  18. for i, key := range allKeys {
  19. xxx[i].ID = key.ID
  20. }
  21. return xxx, nil
  22. }

The problem is that allKeys will override previous query results. I have previously overcome the problem by doing:

  1. keys1, err := models.DSClient().GetAll(ctx, query1, &xxx)
  2. keys2, err := models.DSClient().GetAll(ctx, query2, &xxx)
  3. keys = append(keys1, keys2...)

But I wanted my GetAllXXXByQueryFilters to be more sophisticated and avoid duplicated code, and now I can't seem to figure out how I can store the keys from the for _, filter := range filters loop and then append them all afterwards. So I was hoping that maybe there was a smarter way to do/replace the allKeys = append(keys) line so that it doesn't override previous keys?

答案1

得分: 1

将内容翻译为中文:

追加到切片的方法如下:

  1. allKeys = append(allKeys, keys...)

append函数的第一个参数是切片,其余参数是要追加到切片的元素。append函数返回新的切片。

英文:

Append to the slice like this:

  1. allKeys = append(allKeys, keys...)

The first argument to append is the slice. The remaining arguments are the elements to append to the slice. The append function returns the new slice.

huangapple
  • 本文由 发表于 2017年5月8日 02:36:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/43835217.html
匿名

发表评论

匿名网友

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

确定