Golang Gorm Dynami c Структура назначения - PullRequest
0 голосов
/ 24 апреля 2020

Я хочу написать функцию, которая извлекает запись в базе данных с GORM , где структура назначения - Dynami c. Примерно так:

type User struct {
  ID    uint
  Email string
}

type BigUser struct {
  ID       uint
  Username string
  Role     string
}

func GetRecord(db *gorm.DB, u SomeUserInterfaceTypeOrSomething) {
  db.Find(&u)
}

GetRecord(db, User{})
GetRecord(db, BigUser{})

Итак, если я передаю переменную User struct, я получаю только идентификатор и электронную почту, если я передаю переменную BigUser struct, я получаю все поля базы данных (например, ).

Мне это нужно, потому что GetRecord будет в библиотеке, и я хочу, чтобы тот, кто будет использовать библиотеку, мог передать пользовательскую структуру для извлечения только тех полей, которые он хочет.

Я не знаю, как этого добиться, какой-либо совет или лучшая практика? Я новичок с Golang: D

Ответы [ 2 ]

1 голос
/ 24 апреля 2020

Чтобы передать structure как UserInterface, вам необходимо убедиться, что ваша структура желаний реализует все методы интерфейса.

Пример кода

package main

import "fmt"

type User struct {
    ID    uint
    Email string
}

func (user *User) GetRecord() interface{} {
    // get info from database here
    return &User{
        ID:    user.ID,
        Email: user.Email,
    }
}

type BigUser struct {
    ID       uint
    Username string
    Role     string
}

func (user *BigUser) GetRecord() interface{} {
    // get info from database here
    return &BigUser{
        ID:       user.ID,
        Username: user.Username,
        Role:     user.Role,
    }
}

// While declaring an interface,
// make sure that your desire structures have all those interface methods.
type UserInterface interface {
    GetRecord() interface{}
}

// Function to print the values
func printValues(u UserInterface) {
    fmt.Println(u.GetRecord())
}

func main() {
    var x UserInterface

    x = &User{
        ID:    1,
        Email: "abc@gmail.com",
    }
    printValues(x)

    x = &BigUser{
        ID:       2,
        Username: "YouKnowWhoIam",
        Role:     "ADMIN",
    }
    printValues(x)
}

Вывод

&{1 abc@gmail.com}
&{2 YouKnowWhoIam ADMIN}
1 голос
/ 24 апреля 2020

Передача указателя на интерфейс почти всегда, если не всегда, неверна. Т.е. аргумент, передаваемый вашей функции, ДОЛЖЕН быть указателем. Имея это в виду, вы можете использовать тот же подход, который использует json.Unamrshal или (*gorm.DB).Find, то есть принять пустой интерфейс и декодировать полученный результат в него. И используйте документацию, чтобы сообщить пользователю, что переданное значение должно быть ненулевым указателем, иначе код не будет выполнен.

func GetRecord(db *gorm.DB, u interface{}) {
    db.Find(u) // u must already be a pointer, therefore don't do &u here
}

var u User{}
GetRecord(db, &u) // pass a pointer here

bu := new(BigUser) // new returns a pointer
GetRecord(db, bu) // bu is a pointer already, no need for &bu here
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...