2016-02-26 30 views
12

Bazı web projeleri için Golang Revel kullanıyorum ve şu ana kadar 12 proje yaptım. Hepsinde dönüş türleri nedeniyle çok fazla kod fazlalığım var. Bu iki işlevin bak:Golang'da dinamik tip yapısı nasıl döndürülür?

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 

} 

onlar her ikisi de getiri aynı veri tipi (tip yapı) Görüldüğü gibi. Benim fikrim böyle Dize var geçmesi içindi: Farklı modellerde ama aynı veri türü için tekrar tekrar aynı şeyi yapıyor veri türlerini dönen yerine için sadece bir yardımcı olabilir Bunun gibi

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

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

.

Sorularım şunlardır:

  1. evet doğru docs
  2. Hayır ise beni işaret edebilir Eğer tüm
  3. bu mümkün mü, ben cevap :)
  4. dönmek sonra mutlu daha olacak
+1

Sağ iz @ pregmatch 1 –

cevap

14

Evet, ancak işlevinizin interface{} ve []*interface ürününü döndürmesi gerekir. Bu durumda

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

Eğer orijinal tip içine dönüş değer dağıtmak için Type Switches and/or Type Assertions kullanabilirsiniz.

Örnek

Not: Ben Revel hiç kullanmadıysanız, ancak aşağıdaki pasajı size bir genel bir fikir vermelidir:

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

Cevabınızı, nasıl yapılacağı konusunda biraz daha uzatabilir misiniz? – OscarRyz

+1

BAŞARINIZ! Ayakkabılarını her zaman parlatacağım :). Bir şeyleri nasıl yapacağımı bilmediğimde fazlalık olduğunda nefret ediyorum. Yazdıklarınız proje (ler) den çok fazla kod çıkardı. – pregmatch

+2

Tür dönüşü başarısız olursa, 'ReturnModels (" markalar "). ([] Marka)' panik olacaktır. Bu durumda, '[] * models.Brand' için iddia ediyor olmanız gerekir. Paniğe karşı korumak için virgül, tamam deyimini kullanın: https://golang.org/doc/effective_go.html#interface_conversions – elithrar

İlgili konular