2016-02-26 24 views
12

Tôi đang sử dụng Golang Revel cho một số dự án web và tôi đã làm như 12 dự án trong đó cho đến nay. Trong tất cả chúng tôi có rất nhiều sự thừa mã vì các kiểu trả về. Hãy xem hai chức năng sau:Làm thế nào để trả về cấu trúc kiểu động trong 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 

} 

Như bạn có thể thấy cả hai đều trả về cùng một loại dữ liệu (loại cấu trúc). Ý tưởng của tôi là chỉ để vượt qua chuỗi var như thế này:

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

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

Như thế này tôi có thể chỉ có một helper trả lại kiểu dữ liệu thay vì làm điều tương tự hơn và hơn nữa cho các mô hình khác nhau nhưng kiểu dữ liệu tương tự.

Câu hỏi của tôi là:

  1. Đây có phải là có thể ở tất cả
  2. Nếu có bạn có thể chỉ cho tôi tài liệu đúng
  3. Nếu không, tôi sẽ được nhiều hơn thì rất vui khi được trở lại câu trả lời của bạn :)
+1

ca khúc Ngay @ pregmatch 1 –

Trả lời

14

Có thể, tuy nhiên, chức năng của bạn phải trả lại interface{} chứ không phải []*interface.

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

Trong trường hợp này bạn có thể sử dụng Type Switches and/or Type Assertions để truyền giá trị trả lại vào loại ban đầu.

Ví dụ

Lưu ý: Tôi chưa bao giờ sử dụng Revel, nhưng đoạn sau đây sẽ cho bạn một một ý tưởng chung:

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

Bạn có thể mở rộng câu trả lời của mình thêm một chút về cách thực hiện nó không? – OscarRyz

+1

Bạn TUYỆT VỜI! Tôi sẽ tỏa sáng đôi giày của bạn bất cứ lúc nào :). Tôi ghét khi tôi có dự phòng khi không biết cách làm gì đó. Những gì bạn đã viết chỉ cần loại bỏ rất nhiều mã từ dự án của tôi (s). – pregmatch

+2

Lưu ý rằng 'ReturnModels (" thương hiệu "). ([] Nhãn hiệu)' sẽ hoảng loạn nếu xác nhận kiểu không thành công. Trong trường hợp này, bạn nên xác nhận cho '[] * models.Brand'. Sử dụng dấu phẩy, thành ngữ ok để bảo vệ chống lại sự hoảng loạn: https://golang.org/doc/effective_go.html#interface_conversions – elithrar

Các vấn đề liên quan