I am using gorm package ( https://github.com/jinzhu/gorm ) as my database library in golang. I have many classes (database tables) like "Hotel" or "Package". Duplicating code is not good programming practice. As a silly example - lets assume I want to get first object from each table. I can write this method ( GetFirstHotel
, GetFirstPackage
...) for each object. But better way would be to have just a single method GetFirstItem
, where I would use first param to create object with same class as parameter, then pass it to gorm, which will fill it with data from database, then return it as interface{}
. I tried to use reflect for that, but failed, because I probably don't understand it much.
Maybe I just didn't discover some function in gorm library, or I can't use reflect package properly. How should I implement GetFirstItem
function. Is it possible to have this implemented, or should I rather repeat my code?
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
}
The db.First method returns db reference and hydrates the row into the passed structure.
The closest to your desired method is
func GetFirstItem(item interface{}) error {
return db.First(item).Error
}
This simply requires you keep a reference to the parameter
var firstHotel &Hotel{}
err := GetFirstItem(firstHotel)
Returning the hydrated object for all types would required type parameters (generics). I think you'll find the current situation is workable within limits.
see also: Why no generics in Go?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.