2016-06-14 5 views
0

Я пытаюсь что-то сделать, чтобы привести результаты SQL динамически, в основном я хочу запустить функцию, передав строки и структуру (чтобы получить тип данных и сделать их) и вернуться в интерфейс массив.Golang Structs/Interfaces

Кто-нибудь знает, как я могу это сделать?

Я не хочет пройти прямую "User", как-структуру пары .. это не динамически

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, которые позволяют вам напрямую сканировать в структуры вместо того, чтобы предоставлять каждое поле явно или фрагмент. При этом вашей функции сканирования нужно только принять интерфейс и передать его вслепую на '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

Спасибо :) Вы знаете, как я могу комбинировать StructRow и StructForScan в одной и той же функции? –

+0

Я думаю, что метод, который вы реализовали, довольно прямолинейный :). Также, как указано в комментариях выше, посмотрите https://github.com/jmoiron/sqlx. Я тоже это сделал. Это довольно здорово. –