我正在学习 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())
}
任何帮助解释我为什么这不起作用将不胜感激。
我的第二个问题是在官方
datastore
Go package documentation它说:// 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
的推荐模式是什么?一个应用程序中只有一次?
最佳答案
该文档在 Client.Put()
上非常清楚:
Put saves the entity src into the datastore with the given key. src must be a struct pointer or implement PropertyLoadSaver.
您不传递结构指针或
PropertyLoadSaver
.您传递一个指向接口(interface)类型的指针(如果曾经使用过,您应该很少使用)。在 Go 中,接口(interface)有点像“包装器”类型,它可以包装一个具体的值及其类型,其中包装的值也可能是一个指针。因此,如果需要指针,则指针被包装在接口(interface)中,因此不需要使用指向接口(interface)本身的指针。在某些情况下,它仍然是必需的或有用的,但很少见。在你遇到对它的需要之前,避免它。例如,当您需要接口(interface)类型的反射类型描述符时,请参阅 how to append nil to dynamic type slice by reflect.Append .由于您使用
*Task
作为您的entity
(这是一个指向结构的指针),只需使用 entity
而不是 &entity
.client.Put(ctx, entityKey, entity)
What is the recommended pattern to instantiate a
dsClient
only once in an application?
一种方法是使用包级别(“全局”)变量来存储
datastore.Client
。创建一次。无论您在哪里需要 Client
, 只引用这个变量。
关于pointers - 将接口(interface)实体放入 Google Cloud Datastore 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59808502/