func (s *StructType) Dump() string {
	return s.tree.dump("")
}
Dump dump the id and selector on the field tree.
package gofield
import (
	"bytes"
	"fmt"
	"reflect"
	"unsafe"
	"github.com/henrylee2cn/ameda"
)
type (
	StructType struct {
		tid        int32
		fields     []*FieldType
		fieldGroup map[string][]*FieldType
		depth      int
		tree       *FieldType  
		structNum  int
	}
	FieldType struct {
		id       int
		structID int  
		selector string
		deep     int
		ptrNum   int
		elemTyp  reflect.Type
		elemVal  reflectValue
		rawVal   reflectValue
		parent   *FieldType
		children []*FieldType
		reflect.StructField
	}
	reflectValue struct {
		typ  *uintptr
		ptr  unsafe.Pointer
		flag uintptr
	}
)
func newStructType(a *Accessor, tid int32, structPtr interface{}) *StructType {
	v, ok := structPtr.(reflect.Value)
	if !ok {
		v = reflect.ValueOf(structPtr)
	}
	v = ameda.DereferencePtrValue(v)
	structTyp := v.Type()
	sTyp := &StructType{
		tid:    tid,
		fields: make([]*FieldType, 0, 16),
		tree:   &FieldType{id: rootID, elemTyp: structTyp},
	}
	var structID int
	sTyp.traversalFields(&structID, a.maxDeep, a.iterator, sTyp.tree)
	sTyp.structNum = structID + 1
	if a.groupBy != nil {
		sTyp.groupBy(a.groupBy)
	}
	return sTyp
}
func (s *StructType) traversalFields(structID *int, maxFieldDeep int, iterator IteratorFunc, parent *FieldType) {
	if s.depth >= maxFieldDeep {
		return
	}
	s.depth++
	structTyp := parent.elemTyp
	numField := structTyp.NumField()
	var structFields []*FieldType
L:
	for i := 0; i < numField; i++ {
		f := structTyp.Field(i)
		elemTyp := f.Type
		var ptrNum int
		for elemTyp.Kind() == reflect.Ptr {
			elemTyp = elemTyp.Elem()
			ptrNum++
		}
		_ = reflect.PtrTo(elemTyp)
		_ = reflect.PtrTo(f.Type)
		elemVal := reflect.New(elemTyp)
		rawVal := reflect.New(f.Type)
		field := &FieldType{
			parent:      parent,
			id:          len(s.fields),  
			selector:    joinFieldName(parent.selector, f.Name),
			deep:        s.depth,
			ptrNum:      ptrNum,
			elemTyp:     elemTyp,
			elemVal:     *(*reflectValue)(unsafe.Pointer(&elemVal)),
			rawVal:      *(*reflectValue)(unsafe.Pointer(&rawVal)),
			StructField: f,
		}
		isStruct := elemTyp.Kind() == reflect.Struct
		if isStruct {
			*structID++
			field.structID = *structID
		}
		if iterator != nil {
			switch p := iterator(field); p {
			default:
				fallthrough
			case Take, TakeAndStop:
				parent.children = append(parent.children, field)
				s.fields = append(s.fields, field)
				if isStruct {
					structFields = append(structFields, field)
				}
				if TakeAndStop == p {
					break L
				}
			case SkipOffspring, SkipOffspringAndStop:
				parent.children = append(parent.children, field)
				s.fields = append(s.fields, field)
				if SkipOffspringAndStop == p {
					break L
				}
			case Skip:
				continue L
			case SkipAndStop:
				break L
			}
		} else {
			parent.children = append(parent.children, field)
			s.fields = append(s.fields, field)
			if isStruct {
				structFields = append(structFields, field)
			}
		}
	}
	for _, field := range structFields {
		s.traversalFields(structID, maxFieldDeep, iterator, field)
	}
}
func joinFieldName(parentPath, name string) string {
	return parentPath + "." + name
}
func (s *StructType) groupBy(fn GroupByFunc) {
	s.fieldGroup = make(map[string][]*FieldType, len(s.fields))
	for _, field := range s.fields {
		group, ok := fn(field)
		if ok {
			a := s.fieldGroup[group]
			s.fieldGroup[group] = append(a, field)
		}
	}
}
func (s *StructType) MustAccess(structPtr interface{}) *Struct {
	a, err := s.Access(structPtr)
	if err != nil {
		panic(err)
	}
	return a
}
func (s *StructType) Access(structPtr interface{}) (*Struct, error) {
	tid, ptr := parseStructInfo(structPtr)
	if s.tid != tid {
		return nil, errTypeMismatch
	}
	return newStruct(s, ptr), nil
}
func (s *StructType) Depth() int {
	return s.depth
}
func (s *StructType) RuntimeTypeID() int32 {
	return s.tid
}
func (s *StructType) NumField() int {
	return len(s.fields)
}
func (s *StructType) checkID(id int) bool {
	return id >= 0 && id < len(s.fields)
}
func (s *StructType) FieldType(id int) *FieldType {
	if !s.checkID(id) {
		return nil
	}
	return s.fields[id]
}
func (s *StructType) Filter(fn func(*FieldType) bool) []int {
	list := make([]int, 0, s.NumField())
	for id, field := range s.fields {
		if fn(field) {
			list = append(list, id)
		}
	}
	return list
}
func (s *StructType) GroupTypes(group string) []*FieldType {
	a := s.fieldGroup[group]
	return a
}
func (s *StructType) FieldTree() []*FieldType {
	return s.tree.children
}
func (s *StructType) String() string {
	return s.Dump()
}