datastore: недопустимый тип сущности на Put
Я пытаюсь создать обертку вокруг моих видов, и вот как я это делаю:
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"
}
и причина, по которой я представил type Kind interface
- это:
// 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
}
как вы можете видеть, я использую data.Name()
получить имя вида.
когда я пытаюсь сохранить данные, он жалуется:
datastore: invalid entity type
Я прочитал, что это может быть связано с тем, что не передал ссылку на datastore.Put
, но я делаю это. Есть идеи?
Я должен добавить, что, когда я проверил тип данных (используя reflect.TypeOf()
), то model.Message
это тоже правильно. Так что это конкретный тип.
1 ответов
datastore.Put()
ожидает данные сущности как указатель структуры или любое значение, реализующее PropertyLoadSaver
. Это четко указано в его документе:
src
должен быть указателем структуры или реализациейPropertyLoadSaver
при передаче datastore.Put()
- это значение указателя, указатель на интерфейс. Это правда, что значение, хранящееся в интерфейсе, имеет конкретный тип model.Message
, но это не одно и то же.
вы не можете использовать reflect.TypeOf().String()
потому что в случае интерфейса он сообщает вам конкретный тип, хранящийся в интерфейсе (так что это может ввести в заблуждение).
посмотреть этот код, чтобы продемонстрировать разницу:
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())
выход (попробуйте на Go Playground):
ptr
interface
ptr
struct
все &data
является указателем на интерфейс, и это не разрешено передавать в datastore.Put()
. Вы можете только пройти *Message
, или если вы хотите передать значение интерфейса (не указатель на интерфейс), затем убедитесь, что реализовали PropertyLoadSaver
.