2016-06-14 49 views
0

我正在嘗試做一些事情來使SQL結果動態結構,基本上我想通過傳遞行和結構(獲取數據類型並創建一個)來運行函數,並返回接口陣列。Golang Structs/Interfaces

任何人都知道我該怎麼辦?

我不想通過直接的 「用戶」 結構作爲PARAM ..這不是動態

type User struct{ 
    Id_user int `json:"id_user"` 
    Name string `json:"name"` 
    Email string `json:"email"` 
    Username string `json: "username"` 
} 

func main() { 
    var user User 
    rows, _ := db.Query("SELECT id_user, name, email, username FROM users") 
    json.NewEncoder(w).Encode(StructRow(user, rows)) 
} 

func StructRow(u interface{}, rows *sql.Rows)[]interface{}{ 
    var data []interface{} 
    for rows.Next() { 

     //How i can create a "user" here, dynamically 
     //for Example 
     //var user reflect.TypeOf(u) 

     _ = rows.Scan(StrutForScan(&user)...) 
     data = append(data, user) 
    } 
    return data 
} 

func StrutForScan(u interface{}) []interface{} { 
    val := reflect.ValueOf(u).Elem() 
    v := make([]interface{}, val.NumField()) 
    for i := 0; i < val.NumField(); i++ { 
     valueField := val.Field(i) 
     v[i] = valueField.Addr().Interface() 
    } 
    return v 
} 
+0

我認爲[ORM](https://github.com/jinzhu/gorm)可能會幫助你。 –

+0

爲什麼你要堅持自定義構建一個存儲價值的新界面?難道你只是希望有一種方法可以掃描行而不必知道目標類型是什麼?值得一提的是[sqlx](https://github.com/jmoiron/sqlx),它爲數據庫添加了一些額外的方法,讓您直接掃描到結構中,而不必顯式提供每個字段或一個分片。因此,你的掃描函數只需要接受一個接口並將其盲目地傳遞給'db.Select()'或'db.Get()'。 – Kaedys

+0

哦,好,謝謝。 –

回答

1

改變你的函數StructRow

func StructRow(u interface{}, rows *sql.Rows) []interface{} { 
    var data []interface{} 
    for rows.Next() { 

     t := reflect.TypeOf(u) 
     val := reflect.New(t).Interface() 

     errScan := rows.Scan(StrutForScan(val)...) 
     if errScan != nil { 
      //proper err handling 
     } 
     data = append(data, val) 
    } 
    return data 
} 

將修復它。我猜。 欲瞭解更多反映包轉到:https://golang.org/pkg/reflect/

+0

謝謝:) 你知道我可以如何結合StructRowRow和StructForScan在相同的功能? –

+0

我認爲你實現的方法非常簡單:)。也如上面評論中所述,看看https://github.com/jmoiron/sqlx。我也做過。這非常棒。 –