Как извлечь конкретную структуру из интерфейса

У меня есть несколько таблиц базы данных с конкретной структурой для каждой таблицы. Я использую sqlx. Мои функции для доступа к базе данных отлично работают для каждой конкретной структуры.

Поскольку многие из моих операций с базой данных (например, вставка строки) идентичны во всех таблицах, я бы хотел их немного СУШИТЬ, имея общий набор функций, которые принимают интерфейс и выполняют операции.

В функции, которая принимает интерфейс и вызывает функции sqlx (например, sqlx.Get), мне нужно вытащить конкретную структуру из интерфейса для передачи в sqlx. И я в тупике.

Я прочитал законы отражения. Я прочитал документацию по пакету отражать. Я осмотрел все и, кажется, не могу правильно сложить части.

Конкретный код:

type Persistable interface {
    DbFieldNames() []string
    DbPrepCreate() error
    TableName() string
}

type Session struct {} реализует эти методы и принимается как постоянный.

Этот оператор отлично работает (с явно созданной конкретной структурой.

// src is the Persistable passed into this function
dest := Session{}
err = stmt.Get(&dest, src)

Но использование этой явно созданной структуры в общей функции лишает цели. Я хочу сделать вот что:

dest := SomeFunctionThatExtractsTheConcreteStruct( src ) # таким образом, что я могу передать этот адрес в sqlx.

Я использовал пакет отражения, чтобы изучить переменную src (тип, значение, вид, ...). Я легко вижу, что src содержит * Session. Я могу получить реальную ценность. Но создание конкретного класса из src для перехода в sqlx ускользает от меня.


person Michael Lee Squires    schedule 14.12.2018    source источник


Ответы (1)


У вас есть переменная с именем src с типом Persistable, содержащим *Session. Ваша цель - получить значение interface{}, содержащее *Session, которое будет использоваться в качестве первого аргумента метода Get.

Поскольку Persistable присваивается interface{} (как и все типы), вы можете просто передать src первому аргументу метода Get.

err = stmt.Get(src, args...)
person Cerise Limón    schedule 14.12.2018