5

我有一个结构:

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)

现在我的问题是:如何从结构(或 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
}
4

2 回答 2

2

如果获取字段的值是您的问题,则此代码段应该会有所帮助:

s := reflect.ValueOf(a)
ret := make([]interface{}, s.NumField())
for i := 0; i < s.NumField(); i++ {
    ret[i] = s.Field(i).Interface()
}
于 2013-09-06T02:55:53.280 回答
0

如果创建[]interface{}值是您的问题,那么使用reflect的切片创建机制应该可以很好地工作:

slc := reflect.MakeSlice(InterfaceType, len, cap) // See the link below for creating InterfaceType
slc.Index(0).Set(TargetValue)
return slc.Interface()

(这里是上面提到的链接)。

修改上面的代码以循环遍历结构中的值而不是仅仅循环第 0 个索引应该不会太糟糕。

于 2013-09-05T06:32:02.433 回答