我试图递归地反映一个结构,打印出每个字段的类型。在字段是结构片段的情况下,我希望能够识别数组中保存的类型,然后在该类型上进行反映。
这是一些示例代码
package main import ( "log" "reflect" ) type child struct { Name *string Age int } type Parent struct { Name string Surname *string Children []*child PetNames []string } func main() { typ := reflect.TypeOf(Parent{}) log.Printf("This is a : %s", typ.Kind()) for i := 0; i < typ.NumField(); i++ { p := typ.Field(i) if !p.Anonymous { switch p.Type.Kind() { case reflect.Ptr: log.Printf("Ptr: %s is a type %s", p.Name, p.Type) case reflect.Slice: log.Printf("Slice: %s is a type %s", p.Name, p.Type) subtyp := p.Type.Elem() if subtyp.Kind() == reflect.Ptr { subtyp = subtyp.Elem() } log.Printf("\tDereferenced Type%s", subtyp) default: log.Printf("Default: %s is a type %s", p.Name, p.Type) } } } }
输出看起来像这样:
This is a : struct Default: Name is a type string Ptr: Surname is a type *string Slice: Children is a type []*main.child Dereferenced Type main.child Slice: PetNames is a type []string Dereferenced Type string
当我确定字段类型是指针的一部分时,我可以通过调用subtype.Elem()来推断类型。
输出为“ main.child”
如果我然后尝试反映孩子使用
subSubType := reflect.TypeOf(subtyp) log.Printf("%+v", subSubType)
我得到以下内容:
*reflect.rtype
如何使用反射API遍历子结构的字段?
这是一种方法。
func printType(prefix string, t reflect.Type, visited map[reflect.Type]bool) { // Print the name of this type with opening ( for description. fmt.Printf("%s (", t) // Traverse elements, adding to description as we go. elems: for { switch t.Kind() { case reflect.Ptr: fmt.Print("ptr to ") case reflect.Slice: fmt.Print("slice of ") case reflect.Array: fmt.Printf("array with %d elements of ", t.Len()) default: break elems } t = t.Elem() } // Print the kind of the type and the closing ) of the description. // In the case of a struct, we print the names of the fields and recurse. switch t.Kind() { case reflect.Struct: fmt.Printf("struct with %d fields)\n", t.NumField()) if visited[t] { // Don't blow up on recursive type definition. break } visited[t] = true prefix += " " for i := 0; i < t.NumField(); i++ { f := t.Field(i) fmt.Print(prefix, f.Name, " ") printType(prefix, f.Type, visited) } default: fmt.Printf("%s)\n", t.Kind()) } } func main() { printType("", reflect.TypeOf(Parent{}), make(map[reflect.Type]bool)) }
Parent {}的输出具有以下类型:
type child struct { Name *string Age int } type Parent struct { Name string Surname *string Children []*child PetNames []string Parents [2]*Parent child }
是:
main.Parent (struct with 6 fields) Name string (string) Surname *string (ptr to string) Children []*main.child (slice of ptr to struct with 2 fields) Name *string (ptr to string) Age int (int) PetNames []string (slice of string) Parents [2]*main.Parent (array with 2 elements of ptr to struct with 6 fields) child main.child (struct with 2 fields)
游乐场的例子