切片和界面操作

我最近开始在 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 mapping

func (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 非常陌生,我可能完全错误地处理了这个问题。


摇曳的蔷薇
浏览 153回答 1
1回答

Smart猫小萌

因为该方法在指针接收器上(应该如此),所以使用切片元素的地址:entity := dv.Index(i).Addr().Interface().(Queryable)另一种方法是对结果使用一片指针:var result []*Cameraerr := c.RunQuery(ctx, q, &result)可以编写代码以与 []Camera 或 []*Camera 一起使用,如下所示:var queryableType = reflect.TypeOf((*Queryable)(nil)).Elem()needAddr := !dv.Type().Implements(queryableType)...var entity Queryableif needAddr {    entity = dv.Index(i).Addr().Interface().(Queryable)} else {    entity = dv.Index(i).Interface().(Queryable)}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go