Reflection 反映空'的字段;这是什么类型?

Reflection 反映空'的字段;这是什么类型?,reflection,go,Reflection,Go,我有以下查询生成器功能: func CreateQuery(t interface{}, where string) { var b bytes.Buffer b.WriteString("SELECT ") s := reflect.ValueOf(t).Elem() typeOfT := s.Type() for i := 0; i < s.NumField() - 1; i++ { b.WriteString(fmt.Spr

我有以下查询生成器功能:

func CreateQuery(t interface{}, where string) {
    var b bytes.Buffer
    b.WriteString("SELECT ")

    s := reflect.ValueOf(t).Elem()
    typeOfT := s.Type()

    for i := 0; i < s.NumField() - 1; i++ {
        b.WriteString(fmt.Sprintf("%s, ", typeOfT.Field(i).Name))
    }

    //Last one has no Comma
    b.WriteString(fmt.Sprintf("%s ", typeOfT.Field(s.NumField() - 1).Name))

    b.WriteString(fmt.Sprintf("FROM %s ", typeOfT.Name()))
    b.WriteString(where)
    fmt.Println(b.String())
}
但以下情况引发了“对切片值调用reflect.Value.NumField”恐慌:


如何使函数打印切片的底层结构类型的字段?似乎我想要reflect的
SliceOf
函数的倒数。

您只能在表示结构的
reflect.Type
上调用
NumField
Field
方法(即
t.Kind()==reflect.struct


如果有切片类型,则可以通过
Elem
方法访问包含的类型,该方法返回另一个
reflect.type
。如果切片包含一个结构,那么您可以在此类型上调用
NumField
/
字段

您只能在表示结构的
reflect.type
上调用
NumField
Field
方法(即
t.Kind()==reflect.struct


如果有切片类型,则可以通过
Elem
方法访问包含的类型,该方法返回另一个
reflect.type
。如果切片包含结构,则可以在此类型上调用
NumField
/
Field

可以在切片上迭代,为每个查询调用
CreateQuery

func CreateQueries(t interface{}, where string) {
    v := reflect.ValueOf(t)

    if v.Kind() == reflect.Ptr {
        v = v.Elem()
    }

    if v.Kind() == reflect.Array || v.Kind() == reflect.Slice {
        for i := 0; i < v.Len(); i++ {
            CreateQuery(v.Index(i).Interface(), where)
        }
    }
}
func createquerys(t接口{},其中字符串){
v:=反射值(t)
如果v.Kind()==reflect.Ptr{
v=v.Elem()
}
如果v.Kind()==reflect.Array | | v.Kind()==reflect.Slice{
对于i:=0;i
使用,您可以分别访问每个字段,在上调用
.Interface()
值生成该值的
接口{}
类型表示,使其适合放置
它位于
CreateQuery
函数中(该函数需要一个
接口{}
值)。

您可以迭代切片,为每个查询调用
CreateQuery

func CreateQueries(t interface{}, where string) {
    v := reflect.ValueOf(t)

    if v.Kind() == reflect.Ptr {
        v = v.Elem()
    }

    if v.Kind() == reflect.Array || v.Kind() == reflect.Slice {
        for i := 0; i < v.Len(); i++ {
            CreateQuery(v.Index(i).Interface(), where)
        }
    }
}
func createquerys(t接口{},其中字符串){
v:=反射值(t)
如果v.Kind()==reflect.Ptr{
v=v.Elem()
}
如果v.Kind()==reflect.Array | | v.Kind()==reflect.Slice{
对于i:=0;i
使用,您可以分别访问每个字段,在上调用
.Interface()
值生成该值的
接口{}
类型表示,使其适合放置
它在您的
CreateQuery
函数中(它需要一个
接口{}
值)。

得到了它,所以我需要做一些类似的事情:
typeOfT:=s.Type()
然后
包含typeOfT:=typeOfT.Elem()
。然后函数的其余部分引用了
containedTypeSoft
,而不是
s
TypeSoft
得到了它,所以我需要做如下操作:
TypeSoft:=s.Type()
然后
containedTypeSoft:=TypeSoft.Elem()
。然后,函数的其余部分引用
包含TypeSoft
,而不是
s
TypeSoft
func CreateQueries(t interface{}, where string) {
    v := reflect.ValueOf(t)

    if v.Kind() == reflect.Ptr {
        v = v.Elem()
    }

    if v.Kind() == reflect.Array || v.Kind() == reflect.Slice {
        for i := 0; i < v.Len(); i++ {
            CreateQuery(v.Index(i).Interface(), where)
        }
    }
}