将接口实体放入 Google Cloud Datastore 失败

我正在学习 Go 中的一些基本概念,因此我正在尝试使用类似于我在其他编程语言中所做的数据层抽象,并且我在以下代码中运行时出现以下错误:


Failed to save task: datastore: invalid entity type

代码如下:


package main


import (

    "context"

    "fmt"

    "log"


    "cloud.google.com/go/datastore"

    "github.com/google/uuid"

)


type DatastoreEntity interface {

    Kind() string

    Name() string

}


type Task struct {

    TaskId      string

    Description string

}


func (task *Task) Kind() string {

    return "tasks"

}


func (task *Task) Name() string {

    return task.TaskId

}


func main() {

    task := Task{

        TaskId:      uuid.New().String(),

        Description: "Buy milk",

    }

    SaveEntity(&task)

}


func SaveEntity(entity DatastoreEntity) {

    ctx := context.Background()

    projectId := "my-gcp-project"

    client, err := datastore.NewClient(ctx, projectId)

    if err != nil {

        log.Fatalf("Failed to create client: %v", err)

    }


    entityKey := datastore.NameKey(entity.Kind(), entity.Name(), nil)


    if _, err := client.Put(ctx, entityKey, &entity); err != nil {

        log.Fatalf("Failed to save task: %v", err)

    }


    fmt.Printf("Saved %v: %v\n", entityKey, entity.Name())

}

任何帮助解释我为什么这不起作用将不胜感激。


我的第二个问题是,在官方datastoreGo 包文档中它说如下:


// Create a datastore client. In a typical application, you would create

// a single client which is reused for every datastore operation.

dsClient, err := datastore.NewClient(ctx, "my-project")

if err != nil {

    // Handle error.

}

dsClient在应用程序中仅实例化一次的推荐模式是什么?


心有法竹
浏览 166回答 1
1回答

哆啦的时光机

该文档非常清楚Client.Put():Put 使用给定的键将实体 src 保存到数据存储中。src 必须是结构指针或实现 PropertyLoadSaver。您不传递结构指针也不传递PropertyLoadSaver. 您传递一个指向接口类型的指针(如果曾经使用过,您应该很少使用)。在 Go 中,接口有点像“包装器”类型,它可以包装一个具体的值及其类型,其中包装的值也可能是一个指针。因此,如果需要指针,则指针被包装在接口中,因此不需要使用指向接口本身的指针。在某些情况下,它仍然是必需的或有用的,但很少见。在你遇到对它的需要之前,避免它。例如,当您需要接口类型的反射类型描述符时,请参阅如何通过 reflect.Append 将 nil 附加到动态类型切片。由于您使用*Taskas your entity(这是一个指向结构的指针),只需使用entity而不是&entity.client.Put(ctx, entityKey, entity)dsClient在应用程序中仅实例化一次的推荐模式是什么?一种方法是使用一个包级别(“全局”)变量来存储一次datastore.Client创建的变量。无论您在哪里需要 a Client,只需参考此变量即可。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go