反映基础类型的空切片的字段?

I have the following query builder function:

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())
}

There works fine when called as follows:

var dst FooStruct
CreateQuery(&dst, "")

But the following raises a "call of reflect.Value.NumField on slice Value" Panic:

var dst []FooStruct
CreateQuery(&dst, "")

How I can I make the function print the fields of a slice's underlying struct type? It seems like I want the inverse of reflect's SliceOf function.

You can only call NumField or Field methods on a reflect.Type representing a struct (i.e. t.Kind() == reflect.Struct).

If you have a slice type, you can access the contained type via the Elem method, which returns another reflect.Type. If the slice contains a struct, then you can call NumField/Field on this type.

You can iterate over the slice, calling CreateQuery for every query:

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)
        }
    }
}

Using reflect.Value.Index you can access each field separately, calling .Interface() on the value yields the interface{} type representation of that value, making it suitable to put it in your CreateQuery function (which expects a interface{} value).