猿问

填充作为指针传递给函数的结构数组

我想使用 Google Cloud Platform Datastore 进行数据分页,我在 GCP 的页面 ( https://cloud.google.com/datastore/docs/concepts/queries )上找到了一个使用 Cursors 进行分页的示例,它可以正常工作绝对没问题。

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)

    }

当我需要在此函数中创建一个变量来存储记录,然后将其附加到作为指针传递的结构数组时,我的问题就开始了。


来自谷歌的例子


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.

}


Helenr
浏览 157回答 1
1回答

慕运维8079593

使用反射包:func list(ctx context.Context, kind string, dst interface{}, pageSize int, cursorStr string) string {    client, _ := datastore.NewClient(ctx, "my-proj")    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)    }    // Get reflect value for the result slice.    results := reflect.ValueOf(dst).Elem()    // Allocate new value of the slice element type.     // resultp is pointer to that value.    resultp := reflect.New(results.Type().Elem())    it := client.Run(ctx, query)    _, err := it.Next(resultp.Interface())    for err == nil {        // Append last value to results        results.Set(reflect.Append(results, resultp.Elem())        _, err = it.Next(resultp.Interface())    }    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.}使用指向目标切片的指针调用函数:var data []Taskscursor := list(ctx, "Tasks", &data, 10, "")
随时随地看视频慕课网APP

相关分类

Go
我要回答