2016-02-26 40 views
12

我正在使用Golang Revel进行一些网络项目,并且目前为止我做了12个项目。在他们所有人中,由于返回类型,我有很多代码冗余。看看这两个函数:如何在Golang中返回动态类型结构?

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. 这是不可能的
  2. 如果是的,你可以点我正确的文档
  3. 如果没有,我会更快乐,然后回到你的答案:)
+1

正轨@ pregmatch +1 –

回答

14

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

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

在这种情况下,你可以使用Type Switches and/or Type Assertions投的返回值到它的原始类型。

注:我从未使用过狂欢,但下面的代码片段应该给你一个总体思路:

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

你可以扩展你的答案更多的如何做到这一点? – OscarRyz

+1

你真棒!我会随时擦亮你的鞋子:)。当我不知道如何做某事时,我讨厌自己有冗余。你写的东西只是从我的项目中删除了很多代码。 – pregmatch

+2

请注意,如果类型断言失败,'ReturnModels(“品牌”),([]品牌)'将会发生混乱。在这种情况下,它应该是你应该断言'[] * Models.Brand'。使用逗号,好成语来防止恐慌:https://golang.org/doc/effective_go.html#interface_conversions – elithrar