我最近開始在 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 關注
- 181 瀏覽
添加回答
舉報
0/150
提交
取消