duanluan8390 2016-05-28 00:41
浏览 41
已采纳

数据存储区:Put上的无效实体类型

I am trying to create a wrapper around my Kinds and here is how I am doing it:

package model

import (
    "time"
)

type Kind interface {
    Name() string
}

type Message struct {
    Text      string
    CreatedOn time.Time
    UserId    string
}

func (q Message) Name() string {
    return "MESSAGE"
}

And the reason I introduced type Kind interface is:

// Stores the given model for the the kind in data store
func Store(req *http.Request, data Kind) error {
    ctx := appengine.NewContext(req)
    key := datastore.NewKey(ctx, data.Name(), "", 0, nil)
    _, err := datastore.Put(ctx, key, &data)
    return err
}

As you can see, I am using data.Name() to get the kinds name.

When I try to save the data, it complains about:

datastore: invalid entity type

I read that this could be due to not passing the reference to datastore.Put, but I am doing that. Any idea?

I must add that when I checked the type of data (using reflect.TypeOf()), it is model.Message which is correct too. So it is a concrete type.

  • 写回答

1条回答 默认 最新

  • douxie5176 2016-05-28 13:07
    关注

    datastore.Put() expects the entity data as a struct pointer or any value that implements PropertyLoadSaver. This is clearly stated in its doc:

    src must be a struct pointer or implement PropertyLoadSaver

    What you pass to datastore.Put() is a pointer value, a pointer to an interface. It's true that the value stored in the interface is of concrete type model.Message, but they are not the same.

    You can't use reflect.TypeOf().String() because in case of interface it tells you the concrete type stored in the interface (so it might be misleading).

    See this code to demonstrate the difference:

    var data Kind = Message{}
    fmt.Println(reflect.TypeOf(&data).Kind())
    fmt.Println(reflect.TypeOf(&data).Elem().Kind())
    
    var msg Message = Message{}
    fmt.Println(reflect.TypeOf(&msg).Kind())
    fmt.Println(reflect.TypeOf(&msg).Elem().Kind())
    

    Output (try it on the Go Playground):

    ptr
    interface
    ptr
    struct
    

    All in all, &data is a pointer to an interface, and that is not allowed to be passed to datastore.Put(). You can only pass *Message, or if you want to pass an interface value (NOT a pointer to an interface), then make sure to implement PropertyLoadSaver.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥200 wsl2 vllm qwen1.5部署问题
  • ¥100 有偿求数字经济对经贸的影响机制的一个数学模型,弄不出来已经快要碎掉了
  • ¥15 这个公式写进SIMULINK中的function模块的代码中应该是什么样的
  • ¥15 javaweb登陆的网页为什么不能正确连接查询数据库
  • ¥15 数学建模数学建模需要
  • ¥15 已知许多点位,想通过高斯分布来随机选择固定数量的点位怎么改
  • ¥20 nao机器人语音识别问题
  • ¥15 怎么生成确定数目的泊松点过程
  • ¥15 layui数据表格多次重载的数据覆盖问题
  • ¥15 python点云生成mesh精度不够怎么办