Есть ли способ получить объект без использования пользовательской структуры? - PullRequest
0 голосов
/ 12 сентября 2018

Структура datastore.Entity выглядит очень полезной, и именно так я хочу обрабатывать сущности, но я не вижу никакого API, который бы ее использовал.Большинство функций (таких как Get ) принимают interface{}, который, кажется, работает, только если это структура, которая точно структурирована как входящие данные.

// https://godoc.org/cloud.google.com/go/datastore#Client.Get

ctx := context.Background()
client, err := datastore.NewClient(ctx, "project-id")
if err != nil {
    // TODO: Handle error.
}

type Article struct {
    Title       string
    Description string
    Body        string `datastore:",noindex"`
    Author      *datastore.Key
    PublishedAt time.Time
}
key := datastore.NameKey("Article", "articled1", nil)
article := &Article{}
if err := client.Get(ctx, key, article); err != nil {
    // TODO: Handle error.
}

Как бы я получил эту сущность в обобщенном виде?Что если я не знаю структуру?(Более конкретно, как мне получить экземпляр datastore.Entity вместо этого?)

1 Ответ

0 голосов
/ 12 сентября 2018

Итак, вы хотите «общий» тип, который может содержать любой тип объекта? Пакет datastore уже предоставляет вам такой тип: datastore.PropertyList.

Вот как это можно использовать:

var entity datastore.PropertyList
if err := client.Get(ctx, key, &entity); err != nil {
    // TODO: Handle error.
}

Соответствующие документы от datastore:

Свойства

Содержимое сущности может быть представлено различными типами. Обычно это указатели на структуру, но также могут быть любые типы, которые реализуют интерфейс PropertyLoadSaver. Если вы используете указатель структуры, вам не нужно явно реализовывать интерфейс PropertyLoadSaver; хранилище данных автоматически преобразуется с помощью отражения. Если указатель структуры действительно реализует этот интерфейс, то эти методы будут использоваться в предпочтении поведению по умолчанию для указателей структуры. Структурные указатели напечатаны более строго и их проще использовать; PropertyLoadSavers более гибкие.

Таким образом, вы можете использовать любой тип, который реализует интерфейс datastore.PropertyLoadSaver. Этот тип интерфейса:

type PropertyLoadSaver interface {
    Load([]Property) error
    Save() ([]Property, error)
}

Повторное цитирование из пакета документов :

Интерфейс PropertyLoadSaver

Содержимое сущности также может быть представлено любым типом, который реализует интерфейс PropertyLoadSaver. Этот тип может быть указателем структуры, но это не обязательно. Пакет хранилища данных будет вызывать Load при получении содержимого объекта и Save при помещении содержимого объекта. Возможное использование включает получение несохраненных полей, проверку полей или индексацию поля, только если его значение положительное.

[...] Тип * PropertyList реализует PropertyLoadSaver и поэтому может содержать содержимое произвольной сущности.

...