如何从Go中的循环返回数据?

时间:2019-03-31 12:22:56

标签: for-loop go

我正在尝试将[]*Struct转换为JSON响应,我能够从[]*Struct获取数据并对其进行迭代。我遇到的问题是遍历循环,然后将数据返回到interface{}

我试图将一个接口放到一个接口中,但是我无法维持生计。这是我目前的状况,如果遇到任何问题,我被告知转向StackOverflow。

package main

import (
   "log"
   "context"
   "cloud.google.com/go/datastore"
)

var ctx = context.Background()

type ItemList struct {
    Id    string    `datastore:"_id"`
    Name  string    `datastore:"name"`
}

type Data struct {
    ManyItems   []Item
}

type Item struct {
    Id    string    `json:"id"`
    Name  string    `json:"name"`
}

func Get() ([]*ItemList, error) {
  client, err := datastore.NewClient(ctx, "project-name")
  if err != nil {
     log.Println(err)
  }

  var Response []*ItemList
  query := datastore.NewQuery("query")
  _, err = client.GetAll(ctx, query, &Response)
  if err != nil {
     log.Println(err)
  }

  return Response, error
}

func Read() (interface{}) {
   resp, err := Get()
   if err != nil {
      log.Println(err)
   }

   for i, _ := range resp {
     // this is where i get stuck
     r := &Data{
               ManyItems: Item{
                        Id: resp[i].Id,
                        Name: resp[i].Name,
               },
          }
     return r
   }
}

感谢阅读或可以为我提供指导的任何人,我真的很感激。

2 个答案:

答案 0 :(得分:2)

您可以预先声明一个*Data变量,然后在循环内部,在每次迭代中,将该项目添加到其ManyItems字段中。由于ItemListItem具有相同的结构,即相同的字段具有相同的顺序,因此您可以将一个直接转换为另一个。 (As long as you are on Go 1.8 or newer

func Read() interface{} {
    resp, err := Get()
    if err != nil {
        log.Println(err)
        return nil
    }

    data := &Data{ManyItems: make([]Item, len(resp))}
    for i := range resp {
        data.ManyItems[i] = Item(*resp[i])
    }
    return data
}

但是,如果可能的话,仅返回您已经拥有的切片会更有效,

type ItemList struct {
    Id   string `datastore:"_id" json:"id"`
    Name string `datastore:"name" json:"name"`
}

type Data struct {
    ManyItems []*ItemList
}

func Read() interface{} {
    resp, err := Get()
    if err != nil {
        log.Println(err)
        return nil
    }

    return &Data{ManyItems: resp}
}

答案 1 :(得分:2)

您将在for循环内返回,这只会返回第一项。

我还看到ManyItems是Item([] Item)的数组,并且您分配的是错误的单个Item。

更新: 这里有完整的代码:

// Input Json data
type ItemList struct {
    Id    string    `datastore:"_id"`
    Name  string    `datastore:"name"`
}

//Convert *ItemList to *Item
func (list *ItemList) ToItem() *Item {
    return &Item {
        Id    : list.Id,
        Name  : list.Name,
    }
}
// Output Json data
type Data struct {
    ManyItems   []*Item `json:"data"`
}

//Output json item object
type Item struct {
    Id    string    `json:"id"`
    Name  string    `json:"name"`
}
// The read function
func Read() (string, error) {
   resp, err := Get()
   if err != nil {
      log.Println(err)
      return "", err
   }

   list := make([]Item, len(resp))
   for i, _ := range resp {
     list[i] = resp[i].ToItem()
   }

    b, err := json.Marshal(&Data{list})
    if err != nil {
        fmt.Println(err)
        return "", err
    }

   return string(b), nil
}

测试:Playground