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.
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 implementPropertyLoadSaver
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With