Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return dynamic type struct in Golang?

Tags:

go

revel

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 :)
like image 365
pregmatch Avatar asked Feb 26 '16 16:02

pregmatch


People also ask

How do you return a type in Golang?

To declare the named result or return parameters, just use the return type part of the function signature. Below is the general syntax to declare a function in Golang.

Can you return multiple values from a function how in Golang?

In Golang, we can return multiple values at a time from a single function. Multiple return values can be achieved by changing the return type of the function in the function signature. The (int, int) in this function signature explains that the return type is two integers.


1 Answers

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] } 
like image 147
W.K.S Avatar answered Oct 11 '22 09:10

W.K.S