2016-02-15 1 views
0

J'utilise gorm package (https://github.com/jinzhu/gorm) comme ma bibliothèque de base de données dans golang. J'ai beaucoup de classes (tables de base de données) comme "Hotel" ou "Package". Le code de duplication n'est pas une bonne pratique de programmation. Comme un exemple idiot - laisse supposer que je veux obtenir le premier objet de chaque table. Je peux écrire cette méthode (GetFirstHotel, GetFirstPackage ...) pour chaque objet. Mais mieux serait d'avoir une seule méthode GetFirstItem, où j'utiliserais d'abord param pour créer un objet avec la même classe que le paramètre, puis le passerais à gorm, qui le remplirait de données de la base de données, puis le retournerait comme interface{}. J'ai essayé d'utiliser réfléchir pour cela, mais j'ai échoué, parce que je ne le comprends probablement pas beaucoup.Aller réfléchir avec la bibliothèque gorm

Peut-être que je n'ai juste pas découvert de fonction dans la bibliothèque de gorm, ou je ne peux pas utiliser correctement le module de réflexion. Comment devrais-je mettre en œuvre la fonction GetFirstItem. Est-il possible d'avoir cette implémentation, ou devrais-je plutôt répéter mon 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 
} 

Répondre

2

La méthode db.First renvoie référence db et hydrate la ligne dans la structure adoptée.

Le plus proche de votre méthode souhaitée est

func GetFirstItem(item interface{}) error { 
    return db.First(item).Error 
} 

Cela nécessite simplement vous gardez une référence au paramètre

var firstHotel &Hotel{} 
err := GetFirstItem(firstHotel) 

De retour l'objet hydraté pour tous les types feriez paramètres de type requis (génériques). Je pense que vous trouverez que la situation actuelle est réalisable dans certaines limites.

voir aussi: Why no generics in Go?