Как мне вернуть данные из For-Loop в Go? - PullRequest
0 голосов
/ 31 марта 2019

Я пытаюсь преобразовать []*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 ]

2 голосов
/ 31 марта 2019

Вы возвращаетесь в цикл 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
}

Тест: Детская площадка

2 голосов
/ 31 марта 2019

Вы можете предварительно объявить переменную *Data, а затем внутри цикла, на каждой итерации добавлять элемент в его поле ManyItems.Поскольку ItemList и Item имеют одинаковую структуру, то есть одни и те же поля в одном и том же порядке, вы можете конвертировать одно в другое.( Пока вы находитесь на Go 1.8 или новее )

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}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...