У меня есть:-структураПерейти: Как я могу «распаковать» структуру?
type mystruct struct {
Foo string
Bar int
}
я хотел бы создавать операторы SQL вставки из структур, которые имеют следующий вид:
m := mystruct{ "Hello" , 1 }
query := "INSERT INTO mytbl (foo, bar) VALUES (?,?)"
res,err := db.Exec(query, m.Foo, m.Bar)
Теперь мой вопрос: как я могу сделать последний line динамически из самой структуры (или m)? Я могу получить имена структур, используя reflect
, но я не знаю, как создать срез []interface{}
для вызова db.Exec()
. Это то, что я пробовал: (http://play.golang.org/p/GR1Bb61NFH)
package main
import (
"fmt"
"reflect"
)
type mystruct struct {
Foo string
Bar int
}
func main() {
m := mystruct{"Foo", 1}
fmt.Println(readNames(m))
x := unpackStruct(m)
fmt.Printf("%#v\n", x)
}
func unpackStruct(a interface{}) []interface{} {
// "convert" a to m t
// doesn't work, from 'laws of reflection'
s := reflect.ValueOf(&t).Elem()
typeOfT := s.Type()
for i := 0; i < s.NumField(); i++ {
f := s.Field(i)
fmt.Printf("%d: %s %s = %v\n", i,
typeOfT.Field(i).Name, f.Type(), f.Interface())
}
// this is in principle what I want:
m := mystruct{"Hello", 2}
var ret []interface{}
ret = make([]interface{}, s.NumField())
ret[0] = m.Foo
ret[1] = m.Bar
return ret
}
// works fine:
func readNames(a interface{}) []string {
s := reflect.TypeOf(a)
lenStruct := s.NumField()
ret := make([]string, lenStruct)
for i := 0; i < lenStruct; i++ {
ret[i] = s.Field(i).Name
}
return ret
}
Я не очень понимаю, что ваше недоразумение было, так что я не буду отправлять полный ответ на сейчас, но ошибка в основном заключается в 's: = reflect.ValueOf (& t) .Elem()'. Строка излишне сложна, и я не уверен, что она делает, s: = reflect.ValueOf (a) отлично работает. http://play.golang.org/p/C9cv6uw97k – LinearZoetrope
@ Joror, это именно то, что я хочу. Каким-то образом я не смог понять свое мнение в правильном направлении. Если вы опубликуете это как ответ, я буду рад «принять» его. – topskip
Если аргумент 'a' предназначен для интерфейса, который может содержать любую структуру, то вы можете фактически передать' a' непосредственно в ValueOf, поскольку ValueOf принимает интерфейс в качестве аргумента: 's: = reflect.ValueOf (a) ' – joshlf