Пойди поразмышляй с библиотекой Горм
Я использую пакет gorm ( https://github.com/jinzhu/gorm) в качестве библиотеки базы данных в golang. У меня есть много классов (таблиц базы данных), таких как "Отель" или "Пакет". Дублирование кода не является хорошей практикой программирования. В качестве глупого примера - предположим, я хочу получить первый объект из каждой таблицы. Я могу написать этот метод (GetFirstHotel
, GetFirstPackage
...) для каждого объекта. Но лучше было бы иметь только один метод GetFirstItem
где я использовал бы первый параметр для создания объекта с тем же классом, что и у параметра, затем передал бы его в gorm, который заполнит его данными из базы данных, а затем вернет его как interface{}
, Я пытался использовать отражение для этого, но не получилось, потому что я, наверное, не очень понимаю.
Возможно, я просто не обнаружил какую-то функцию в библиотеке gorm, или я не могу правильно использовать отражающий пакет. Как я должен реализовать GetFirstItem
функция. Возможно ли реализовать это, или мне лучше повторить мой код?
package main
import (
"github.com/jinzhu/gorm"
)
var db gorm.DB
type Hotel struct {
ID int64
Name string
Lat float64
Lon float64
}
type Package struct {
ID int64
Name string
Text string
}
func GetFirstHotel() (hotel Hotel) {
db.First(&hotel)
}
func GetFirstPackage() (pack Package) {
db.First(&pack)
}
func main() {
var firstHotel, firstPackage interface{}
//first method
firstHotel = GetFirstHotel()
firstPackage = GetFirstPackage()
//method i want to use
firstHotel = GetFirstItem(Hotel{})
firstPackage = GetFirstItem(Package{})
}
func GetFirstItem(item interface{}) interface{} {
//how to implement this?
//probably with some use of reflect package
}
1 ответ
Метод db.First возвращает ссылку на db и переводит строку в переданную структуру.
Наиболее близким к вашему желаемому методу является
func GetFirstItem(item interface{}) error {
return db.First(item).Error
}
Это просто требует, чтобы вы сохранили ссылку на параметр
var firstHotel &Hotel{}
err := GetFirstItem(firstHotel)
Возвращение гидратированного объекта для всех типов потребовало бы параметров типа (обобщений). Я думаю, вы найдете, что текущая ситуация работоспособна в определенных пределах.
см. также: почему нет генериков в Go?