gpt4 book ai didi

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

转载 作者:数据小太阳 更新时间:2023-10-29 03:10:15 24 4
gpt4 key购买 nike

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

Google 提供的示例对变量 var tasks []Taskvar 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)
}

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

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{} 的变量中p>

最佳答案

使用 reflect包裹:

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

使用指向目标 slice 的指针调用函数:

var data []Tasks
cursor := list(ctx, "Tasks", &data, 10, "")

关于go - 填充作为指针传递给函数的结构数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53254726/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com