如何在Golang中返回动态类型结构? [英] How to return dynamic type struct in Golang?

查看:438
本文介绍了如何在Golang中返回动态类型结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Golang Revel进行一些网络项目,到目前为止,我确实喜欢12个项目。在他们所有人中,由于返回类型,我有很多代码冗余。看看这两个功能:

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

//在rethinkdb上做一些选择并填充正确的模型
var brands [] * models.Brand
rows.All(& brand)

返回品牌


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

//在rethinkdb上做一些选择并填充正确的模型
var posts [] * models.Post
rows.All(& posts)

return posts

}

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

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

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

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

我的问题是:


  1. 这完全有可能

  2. 如果是的话,你可以指向我的权利文档

  3. 如果不是,我会更乐意回复您的答案:

  4. ol>

    解决方案

    可以,但是您的函数应该返回 interface {} code $ [] * interface 。

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

    在这种情况下,您可以使用键入开关和/或类型断言将返回值转换为原始类型。



    <注:我从来没有使用Revel,但下面的代码片段应该给你一个大致的想法:



    游乐场

     包主要

    导入fmt

    类型结构{
    作者字符串
    内容字符串
    }

    类型品牌struct {
    名称字符串
    }

    var数据库映射[字符串]接口{}

    func init(){
    database = make(map [string] interface {})

    brands:= make([] Brand,2)
    品牌{品牌} {品牌} =品牌

    posts:= make([] Post,1)
    posts [0] =发帖{作者:JKR,内容:无论}

    database [posts] = posts
    }

    func main(){
    fmt.Println(品牌列表:)
    if品牌,确定:= ReturnModels(品牌)。([]品牌);好的{
    fmt.Printf(%v,品牌)
    }

    fmt.Println(\\\
    帖子列表:)
    如果帖子, OK:= ReturnModels(posts)。([] Post); OK {
    fmt.Printf(%v,posts)
    }

    }

    func ReturnModels(modelName string)interface {} {

    返回数据库[模型名称]
    }


    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 :)

    解决方案

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

    这篇关于如何在Golang中返回动态类型结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆