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

huangapple go评论86阅读模式
英文:

How to return dynamic type struct in Golang?

问题

我正在使用Golang Revel进行一些Web项目,到目前为止已经完成了12个项目。在所有这些项目中,由于返回类型的原因,我有很多代码冗余。看看这两个函数:

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

    //在rethinkdb上执行一些查询,并填充正确的模型
    var brands []*models.Brand
    rows.All(&brands)

    return brands

}

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

    //在rethinkdb上执行一些查询,并填充正确的模型
    var posts []*models.Post
    rows.All(&posts)

    return posts

}

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

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

    //使用modelName进行rethinkdb查询,并返回modelName的[]*interface{}
}

这样,我可以只有一个辅助函数来返回不同模型但相同数据类型的数据,而不是为不同模型重复相同的操作。

我的问题是:

  1. 这种做法是否可行?
  2. 如果是,你能指导我查阅正确的文档吗?
  3. 如果不行,我将非常乐意听取你的答案 如何在Golang中返回动态类型的结构体?
英文:

I am using Golang Revel for some web project and I did like 12 projects in that so far. In all of them I have a lot of code redundancy because of return types. Look at this two functions:

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

}

As you can see they they both returns same type of data (type struct).
My idea was just to pass string var like this:

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

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

Like this I can have just one helper for returning data types instead of
doing same thing over and over again for different models but same data type.

My questions are:

  1. Is this possible at all
  2. If yes can you point me to right docs
  3. If no, I will be more then happy to return your answer 如何在Golang中返回动态类型的结构体?

答案1

得分: 47

是的,这是可能的,但是你的函数应该返回interface{}而不是[]*interface

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

在这种情况下,你可以使用类型切换和/或类型断言将返回值转换为其原始类型。

示例

注意:我从未使用过Revel,但以下代码片段应该给你一个大致的想法:

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]
}
英文:

Yes it's possible however your function should return interface{} and not []*interface.

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

In this case you could use Type Switches and/or Type Assertions to cast the return value into it's original type.

Example

Note: I've never used Revel, but the following snippet should give you an a general idea:

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

huangapple
  • 本文由 发表于 2016年2月27日 00:51:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/35657362.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定