import "cloud.google.com/go/datastore"
type Storage[K comparable, V kv.Expirable] struct {
client *datastore.Client
projectID string
kind string
prefix string
}
func (s Storage[K, V]) Get(ctx context.Context, key string) (V, error) {
var value V
_, err := s.client.RunInTransaction(ctx, func(tx *datastore.Transaction) error {
k := s.key(key)
err := tx.Get(k, &value)
if err == nil {
value.UpdateLastAccessAt(time.Now())
_, err = tx.Put(k, &value)
return err
}
if errors.Is(err, datastore.ErrNoSuchEntity) {
return kv.ErrNoEntityFound
}
return err
})
return value, err
}
type Expirable interface {
UpdateLastAccessAt(t time.Time)
SetCreatedAt(t time.Time)
SetExpireAt(t time.Time, ttl uint64)
}
我有一个
Storage[K, V]
用于在 Google Cloud Datastore 中存储不同类型。这个想法是使用泛型。然而,函数tx.Get
不起作用,返回实体未知的错误,因为value
被传递给tx.Get
,它不知道为什么要序列化。
使用泛型从数据库序列化值的方式是什么?最明显的想法是传递要序列化的类型作为函数的输入,并检查要序列化的类型。你还有其他更好的想法吗?
使用
reflect
它会以这种方式工作
var value V
valueType := reflect.TypeOf(value).Elem()
v := reflect.New(valueType).Interface().(V)