如何在Golang中返回动态类型结构?

pre*_*tch 18 go revel

我正在使用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

}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,它们都返回相同类型的数据(类型结构).我的想法就是像这样传递字符串var:

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

    //do rethinkdb select with modelName and return []*interface{} for modelName
}
Run Code Online (Sandbox Code Playgroud)

像这样我可以只有一个帮助器来返回数据类型,而不是为不同的模型反复做同样的事情,但是相同的数据类型.

我的问题是:

  1. 这有可能吗?
  2. 如果是,你可以指向正确的文档
  3. 如果没有,我会更乐意回复你的答案:)

W.K*_*K.S 27

是的,但是你的功能应该可以返回interface{}而不是[]*interface.

func (c Helper) ReturnModels(modelName string) interface{} {}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您可以使用Type Switches和/或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]
}
Run Code Online (Sandbox Code Playgroud)

  • 你太棒了!我会随时擦亮你的鞋子:).当我不知道如何做某事时我讨厌.你写的只是从我的项目中删除了很多代码. (4认同)
  • 请注意,如果类型断言失败,`ReturnModels("brands").([] Brand)`将会发生混乱.在这种情况下,你应该断言`[]*models.Brand`.使用逗号,ok成语来防止恐慌:https://golang.org/doc/effective_go.html#interface_conversions (2认同)