如何在 Golang 中 return 动态类型结构?
How to return dynamic type struct in Golang?
我正在为一些 Web 项目使用 Golang Revel,到目前为止我确实喜欢其中的 12 个项目。由于 return 类型,在所有这些中我都有很多代码冗余。看看这两个函数:
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
}
如您所见,它们都是 return 相同类型的数据(结构类型)。
我的想法只是像这样传递字符串变量:
func (c Helper) ReturnModels(modelName string) []*interface{} {
//do rethinkdb select with modelName and return []*interface{} for modelName
}
像这样,我可以只有一个助手来处理 returning 数据类型,而不是
对不同的模型但相同的数据类型一遍又一遍地做同样的事情。
我的问题是:
- 这可能吗
- 如果是,你能指点我正确的文档吗
- 如果没有,我会更乐意return你的回答:)
可以,但是您的函数应该 return interface{}
而不是 []*interface
.
func (c Helper) ReturnModels(modelName string) interface{} {}
在这种情况下,您可以使用 Type Switches and/or Type Assertions 将 return 值转换为其原始类型。
例子
注意:我从未使用过 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]
}
我正在为一些 Web 项目使用 Golang Revel,到目前为止我确实喜欢其中的 12 个项目。由于 return 类型,在所有这些中我都有很多代码冗余。看看这两个函数:
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
}
如您所见,它们都是 return 相同类型的数据(结构类型)。 我的想法只是像这样传递字符串变量:
func (c Helper) ReturnModels(modelName string) []*interface{} {
//do rethinkdb select with modelName and return []*interface{} for modelName
}
像这样,我可以只有一个助手来处理 returning 数据类型,而不是 对不同的模型但相同的数据类型一遍又一遍地做同样的事情。
我的问题是:
- 这可能吗
- 如果是,你能指点我正确的文档吗
- 如果没有,我会更乐意return你的回答:)
可以,但是您的函数应该 return interface{}
而不是 []*interface
.
func (c Helper) ReturnModels(modelName string) interface{} {}
在这种情况下,您可以使用 Type Switches and/or Type Assertions 将 return 值转换为其原始类型。
例子
注意:我从未使用过 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]
}