Как вернуть структуру динамического типа в Голанге?

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

func (c Helper) Brands() []*models.Brand{

    //do some select on rethinkdb and populate correct model
    var brands []*models.Brand
    rows.All(&brands)

    return brands

}

func (c Helper) BlogPosts() []*models.Post{

    //do some select on rethinkdb and populate correct model
    var posts []*models.Post
    rows.All(&posts)

    return posts

}

Как вы можете видеть, они оба возвращают одинаковый тип данных (тип struct). Моя идея состояла в том, чтобы передать строку var следующим образом:

func (c Helper) ReturnModels(modelName string) []*interface{} {

    //do rethinkdb select with modelName and return []*interface{} for modelName
}

Подобно этому, у меня может быть только один помощник для возврата типов данных вместо повторять то же самое снова и снова для разных моделей, но с тем же типом данных.

Мои вопросы:

  • Возможно ли это вообще
  • Если да, вы можете указать мне правильные документы
  • Если нет, я буду более счастлив ответить на ваш ответ:)

Ответ 1

Да, возможно, однако ваша функция должна возвращать interface{}, а не []*interface.

func (c Helper) ReturnModels(modelName string) interface{} {}

В этом случае вы можете использовать Type Switchches и/или Type Assertions для перевода возвращаемого значения в исходный тип.

Пример

Примечание. Я никогда не использовал Revel, но следующий фрагмент должен дать вам общую идею:

Игровая площадка

package main

import "fmt"

type Post struct {
    Author  string
    Content string
}

type Brand struct {
    Name string
}

var database map[string]interface{}

func init() {
    database = make(map[string]interface{})

    brands := make([]Brand, 2)
    brands[0] = Brand{Name: "Gucci"}
    brands[1] = Brand{Name: "LV"}

    database["brands"] = brands

    posts := make([]Post, 1)
    posts[0] = Post{Author: "J.K.R", Content: "Whatever"}

    database["posts"] = posts
}

func main() {
    fmt.Println("List of Brands: ")
    if brands, ok := ReturnModels("brands").([]Brand); ok {
        fmt.Printf("%v", brands)
    }

    fmt.Println("\nList of Posts: ")
    if posts, ok := ReturnModels("posts").([]Post); ok {
        fmt.Printf("%v", posts)
    }

}

func ReturnModels(modelName string) interface{} {

    return database[modelName]
}