Я хочу выполнить разбиение на страницы данных в хранилище данных Google Cloud Platform, и я нашел пример на странице GCP (https://cloud.google.com/datastore/docs/concepts/queries) для работы с курсорами, и он работает абсолютно нормально.
Пример, предоставленный Google, жестко закодировал переменные var tasks []Task
и var task Task
, и я хотел бы создать функцию для повторного использования , где я могу передать указатель на массив структуры через параметр, набранный interface{}
и получить эту структуру, заполненную этой функцией. Например:
type MyStruct1 struct {
F1 string
}
type MyStruct2 struct {
F1 int
}
func list(ctx context.Context, cursorStr string, data interface{}) {
...
}
func main() {
mystruct1 := make([]MyStruct1, 0)
list(ctx, "", &mystruct1)
mystruct2 := make([]MyStruct2, 0)
list(ctx, "", &mystruct2)
}
Моя проблема начинается, когда мне нужно создать в этой функции переменную для хранения записи, а затем добавить ее в массив struct, переданный в качестве указателя.
Пример из Google
func SnippetIterator_Cursor() {
ctx := context.Background()
client, _ := datastore.NewClient(ctx, "my-proj")
cursorStr := ""
// [START datastore_cursor_paging]
const pageSize = 5
query := datastore.NewQuery("Tasks").Limit(pageSize)
if cursorStr != "" {
cursor, err := datastore.DecodeCursor(cursorStr)
if err != nil {
log.Fatalf("Bad cursor %q: %v", cursorStr, err)
}
query = query.Start(cursor)
}
// Read the tasks.
var tasks []Task << THIS IS WHAT I WANT TO BE GENERIC
var task Task. << THIS IS WHAT I WANT TO BE GENERIC
it := client.Run(ctx, query)
_, err := it.Next(&task)
for err == nil {
tasks = append(tasks, task)
_, err = it.Next(&task)
}
if err != iterator.Done {
log.Fatalf("Failed fetching results: %v", err)
}
// Get the cursor for the next page of results.
nextCursor, err := it.Cursor()
// [END datastore_cursor_paging]
_ = err // Check the error.
_ = nextCursor // Use nextCursor.String as the next page's token.
}
Моя общая функция на основе кода выше
func list(ctx context.Context, kind string, data interface{}, pageSize int, cursorStr string) string {
query := datastore.NewQuery(kind).Limit(pageSize)
if cursorStr != "" {
cursor, err := datastore.DecodeCursor(cursorStr)
if err != nil {
log.Fatalf("Bad cursor %q: %v", cursorStr, err)
}
query = query.Start(cursor)
}
it := query.Run(ctx)
// HERE IS WHERE THE PROBLEM STARTS
var vet []interface{}
var rec interface{}
k, err := it.Next(rec)
if err != nil {
log.Println(err.Error())
}
for err == nil {
log.Println(k, rec) // PROBLEM: The key comes ok but rec comes nil
vet = append(vet, rec)
k, err = it.Next(rec)
}
log.Println(vet) // PROBLEM: vet has only nils
nextCursor, err := it.Cursor()
if err != nil {
log.Println(err.Error())
}
data = vet
return nextCursor.String()
}
func TestListFunc() {
data := make([]Tasks, 0)
cursor := list(ctx, "Tasks", &data, 10, "")
x, _ := json.MarshalIndent(data, " ", " ")
log.Println(string(x))
}
ПРОБЛЕМА: Итератор хранилища данных .Next()
, похоже, не хранит запись в переменной типа interface{}