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

I'm trying to convert a []*Struct to a JSON response, I'm able to get the data from the []*Struct and iterate over it. The part I get stuck around is the iterating over a loop then returning the data to an interface{}

I've tried to putting an interface in an interface, but I just can't make ends meet. Here's what I have at the moment, I was told to turn to StackOverflow if I had any issues.

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
   }
}

Thank you to anyone who reads this or can provide me some sort of guidance, I really appreciate it.

You can predeclare a *Data variable and then inside the loop, on each iteration add the item to its ManyItems field. Since ItemList and Item have the same structure, ie the same fields in the same order, you can convert directly one to the other. (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
}

However if possible it would be more efficient to just return the slice you already have, something like this.

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}
}

You are returning inside the for loop and this will only return the first item.

Also I see that ManyItems is an array of Item ([]Item) and you are assigning a single Item which is wrong.

Update: Here you have the complete code:

// 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
}

Test: Playground