2016-02-26 15 views
12

私はいくつかのWebプロジェクトにGolang Revelを使用しています。これまでに12プロジェクトが好きでした。それらのすべてでは、戻り値の型のためにコード冗長性がたくさんあります。この2つの関数を見てください:Golangで動的な構造体を返す方法は?

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 

} 

これらの2つの関数は、同じタイプのデータ(型構造体)を返します。 私の考えでは、このような文字列のVAR渡すだけだった:私は、異なるモデルが、同じデータ型に対して何度も何度も同じことをやってデータ型を返す代わりに のためのちょうど1つのヘルパーを持つことができますこのよう

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

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

を。

私の質問は次のとおりです。yesあなたが右のドキュメント

  • に私を指すことができる場合

    1. はありません場合、私はあなたの答えを返すことがもっとして幸せになりますすべての
    2. で可能これです:)
  • +1

    右トラックの@ pregmatch 1 –

    答えて

    14

    はい、あなたの関数はinterface{}であり、[]*interfaceではありません。この場合

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

    あなたはそれの元の型に戻り値をキャストするType Switches and/or Type Assertionsを使用することができます。

    注:私はレヴェルを使用したことがありませんが、次のスニペットはあなたの一般的なアイデアを与える必要があります。

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

    をあなたはそれをどうやって行うのか、あなたの答えをもう少し広げることができますか? – OscarRyz

    +1

    あなたは素晴らしいです!いつでもあなたの靴を輝かせます:)。私は何かをする方法がわからないときに冗長性があるときは嫌いです。あなたが書いたことは、私のプロジェクトから多くのコードを削除しました。 – pregmatch

    +2

    タイプアサーションに失敗した場合、 'ReturnModels(" brands ")([] Brand)'はパニックになることに注意してください。この場合は '[*] models.Brand'を宣言する必要があります。パニックを防ぐには、カンマ、okのイディオムを使用します。https://golang.org/doc/effective_go.html#interface_conversions – elithrar