【问题标题】:How to return dynamic type struct in Golang?如何在 Golang 中返回动态类型结构?
【发布时间】:2016-02-26 16:51:09
【问题描述】:

我正在将 Golang Revel 用于一些 Web 项目,到目前为止,我确实喜欢其中的 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

}

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

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

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

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

我的问题是:

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

【问题讨论】:

  • 正确的轨道@pregmatch +1

标签: go revel


【解决方案1】:

是的,但您的函数应该返回 interface{} 而不是 []*interface

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

在这种情况下,您可以使用Type Switches and/or Type Assertions 将返回值转换为它的原始类型。

示例

注意:我从未使用过 Revel,但下面的 sn-p 应该可以让您大致了解一下:

Playground

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]
}

【讨论】:

  • 您能否进一步扩展您的答案以说明如何做到这一点?
  • 你太棒了!我会随时擦你的鞋子:)。我讨厌当我有多余的时候不知道如何做某事。你写的只是从我的项目中删除了很多代码。
  • 请注意,如果类型断言失败,ReturnModels("brands").([]Brand) 将出现恐慌。在这种情况下,您应该为[]*models.Brand 断言。使用逗号,ok 成语防止恐慌:golang.org/doc/effective_go.html#interface_conversions
  • 好点!我更新了我的示例以包含 comma, ok 模式。
  • 我刚刚删除了 5 个冗余方法文件。太好了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
相关资源
最近更新 更多