我最近开始在 Google App Engine 上使用 Go 进行编程,但遇到了障碍。我来自 Java 领域,所以适应 Go 有点困难。我想要一个方法,允许我传入一个指向切片的指针,然后我可以将其传递到datastore.GetAll调用中以检索结果。然后我想遍历结果并使用断言将其转换为特定接口 (Queryable) 以调用方法 Map()。最初,我的功能正常:func (s ProjectService) RunQuery(context context.Context, q *datastore.Query, projects *[]Project) error { keys, err := q.GetAll(context, projects) if err != nil { return err } for i, key := range keys { (*projects)[i].Id = key.Encode() (*projects)[i].CompanyId = (*projects)[i].Company.Encode() } return nil}我想要一个更通用的方法,可以应用于任何实现Queryable接口的实体。这个想法是有一个钩子,允许我在检索结果后执行一些后期处理。我已经查看了ProperyLoadSaver界面,但是我无法访问与实体关联的实际密钥。我想在实体中存储 datastore.Key 的字符串表示形式。这是Queryable界面:type Queryable interface { Map(*datastore.Key) error}这是我坚持到 GAE 存储的示例实体:type Camera struct { Id string `datastore:"-"` ProjectId string `datastore:"-"` Name string Project *datastore.Key `json:"-"` Active bool Timestamp Timestamp}// Implement Queryable interface. Let me perform any additional mappingfunc (c *Camera) Map(key *datastore.Key) error { c.Name = "Maybe do other things here" c.Id = key.Encode() return nil}这个想法是有类似下面的片段的东西。func (c Crud) RunQuery(context context.Context, q *datastore.Query, entities interface{}) error { keys, err := q.GetAll(context, entities) v := reflect.ValueOf(entities) dv := v.Elem()但是,当它执行时,它会出现以下情况:PANIC: interface conversion: entity.Camera is not entity.Queryable: missing method Map goroutine 9 [running]:作为说明,我意识到执行断言的适当方法是 if as,ok := elem.(Type); ok {}但我只是想看看错误是什么我猜我收到这个错误是因为我用指针接收器定义了我的参数,func (c *Camera) Map(key *datastore.Key) error 而不是 func (c Camera) Map(key *datastore.Key) error 但是,我想修改实际值。我哪里出错了?我的 Java-ness 显示出来了吗?由于我对 Go 非常陌生,我可能完全错误地处理了这个问题。
1 回答
Smart猫小萌
TA贡献1911条经验 获得超7个赞
因为该方法在指针接收器上(应该如此),所以使用切片元素的地址:
entity := dv.Index(i).Addr().Interface().(Queryable)
另一种方法是对结果使用一片指针:
var result []*Camera
err := c.RunQuery(ctx, q, &result)
可以编写代码以与 []Camera 或 []*Camera 一起使用,如下所示:
var queryableType = reflect.TypeOf((*Queryable)(nil)).Elem()
needAddr := !dv.Type().Implements(queryableType)
...
var entity Queryable
if needAddr {
entity = dv.Index(i).Addr().Interface().(Queryable)
} else {
entity = dv.Index(i).Interface().(Queryable)
}
- 1 回答
- 0 关注
- 152 浏览
添加回答
举报
0/150
提交
取消