Dynamic Struct Type Return in Golang
In Revel projects, there can often be significant redundancy in return types across different models.
Consider these two functions:
func (c Helper) Brands() []*models.Brand { // Select from rethinkdb and populate models.Brand var brands []*models.Brand rows.All(&brands) return brands } func (c Helper) BlogPosts() []*models.Post { // Select from rethinkdb and populate models.Post var posts []*models.Post rows.All(&posts) return posts }
Both functions return the same type of data (pointers to slices of structs). To reduce redundancy, one idea is to create a generic return function that returns an interface{} capable of representing different types.
func (c Helper) ReturnModels(modelName string) interface{} { // Select from rethinkdb based on modelName and return interface{} }
With this approach, there would be only one return function, simplifying code and reducing redundancy.
However, it's important to note that returning interface{} comes with caveats:
The following code example demonstrates this approach:
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 := []Brand{ {Name: "Gucci"}, {Name: "LV"}, } database["brands"] = brands posts := []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] }
The above is the detailed content of How Can Golang's Dynamic Struct Type Return Improve Code Efficiency While Managing Type Safety Risks?. For more information, please follow other related articles on the PHP Chinese website!