github.com/456vv/valexa@v1.0.2-0.20200706152242-1fb922d71ce5/Reflect.go (about) 1 package valexa 2 import ( 3 "reflect" 4 "fmt" 5 ) 6 7 8 9 //ForMethod 遍历方法 10 // x interface{} 类型 11 // string 字符串 12 func ForMethod(x interface{}) string { 13 var t = reflect.TypeOf(x) 14 var s string 15 for i:=0; i<t.NumMethod(); i++ { 16 tm := t.Method(i) 17 s += fmt.Sprintf("%d %s %s\t\t= %v \n", tm.Index, tm.PkgPath, tm.Name, tm.Type) 18 } 19 return s 20 } 21 22 //ForType 遍历字段 23 // x interface{} 类型 24 // string 字符串 25 func ForType(x interface{}) string { 26 return forType(x, "") 27 } 28 func forType(x interface{}, str string) string { 29 var ( 30 v, z reflect.Value 31 f reflect.StructField 32 t reflect.Type 33 k interface{} 34 s string 35 ) 36 37 v = reflect.ValueOf(x) 38 v = inDirect(v) 39 if v.Kind() == reflect.Invalid || v.Kind() != reflect.Struct { 40 s += fmt.Sprintf("无法解析(%s): %#v\r\n", v.Kind(), x) 41 return s 42 } 43 t = v.Type() 44 for i := 0; i < t.NumField(); i++ { 45 f = t.Field(i) 46 z = inDirect(v.Field(i)) 47 k = typeSelect(z) 48 s += fmt.Sprintf("%s %v %v %v\t%v `%v` = %v\r\n", str, f.Index, f.PkgPath, f.Name, f.Type, f.Tag, k) 49 if z.Kind() == reflect.Struct && z.CanInterface() { 50 s += forType(z.Interface(), " "+str) 51 } 52 } 53 return s 54 } 55 56 57 58 //TypeSelect 类型选择 59 // v reflect.Value 映射一种未知类型的变量 60 // interface{} 读出v的值 61 func TypeSelect(v reflect.Value) interface{} { 62 return typeSelect(v) 63 } 64 func typeSelect(v reflect.Value) interface{} { 65 66 switch v.Kind() { 67 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 68 return v.Int() 69 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 70 return v.Uint() 71 case reflect.Float32, reflect.Float64: 72 return v.Float() 73 case reflect.Bool: 74 return v.Bool() 75 case reflect.Complex64, reflect.Complex128: 76 return v.Complex() 77 case reflect.Invalid: 78 return nil 79 case reflect.Slice, reflect.Array: 80 if v.CanInterface() { 81 return v.Interface() 82 } 83 var t []interface{} 84 for i:=0; i<v.Len(); i++ { 85 t = append(t, typeSelect(v.Index(i))) 86 } 87 return t 88 default: 89 if v.CanInterface() { 90 return v.Interface() 91 } 92 return v.String() 93 } 94 } 95 96 //InDirect 指针到内存 97 // v reflect.Value 映射引用为真实内存地址 98 // reflect.Value 真实内存地址 99 func InDirect(v reflect.Value) reflect.Value { 100 return inDirect(v) 101 } 102 func inDirect(v reflect.Value) reflect.Value { 103 for ; v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface; v = v.Elem() {} 104 return v 105 } 106 107 //DepthField 快速深入读取字段 108 // s interface{} Struct 109 // ndex ... interface{} 字段 110 // field interface{} 字段 111 // err error 错误 112 // 例: 113 // type A struct { 114 // B 115 // } 116 // type B struct { 117 // C 118 // F map[string]string 119 // G []string 120 // } 121 // type C struct { 122 // D int 123 // } 124 // func main(){ 125 // a := A{} 126 // fidld, err := DepthField(a, "B", "C", "D") 127 // fmt.Println(fidld, err) 128 // //0 <nil> 129 // } 130 func DepthField(s interface{}, index ... interface{}) (field interface{}, err error) { 131 field = s 132 for _, i := range index { 133 field, err = depthField(field, i) 134 if err != nil { 135 return nil, err 136 } 137 } 138 return field, nil 139 } 140 141 func depthField(s interface{}, index interface{}) (interface{}, error) { 142 sv := reflect.ValueOf(s) 143 sid := InDirect(sv) 144 var reflectValue reflect.Value 145 switch sid.Kind() { 146 case reflect.Struct: 147 reflectValue = sid.FieldByName(index.(string)) 148 case reflect.Map: 149 if sid.IsNil() { 150 return nil, fmt.Errorf("valexa: 该字段是 nil。错误的字段名为(%#v)", index) 151 } 152 reflectValue = sid.MapIndex(reflect.ValueOf(index)) 153 case reflect.Slice, reflect.Array: 154 if sid.Len() > index.(int) { 155 reflectValue = sid.Index(index.(int)) 156 } 157 default: 158 return nil, fmt.Errorf("valexa: 非结构类型,无法正确读取。错误的类型为(%s)", sid.Kind()) 159 } 160 if reflectValue.Kind() == reflect.Invalid { 161 return nil, fmt.Errorf("valexa: 该字段不是有效。错误的字段名为(%#v)", index) 162 } 163 return TypeSelect(reflectValue), nil 164 }