github.com/zhiqiangxu/util@v0.0.0-20230112053021-0a7aee056cd5/reflect.go (about) 1 package util 2 3 import ( 4 "reflect" 5 ) 6 7 // ReplaceFuncVar for replace funcVar with fn 8 func ReplaceFuncVar(funcVarPtr interface{}, fn func(in []reflect.Value) (out []reflect.Value)) { 9 10 v, ok := funcVarPtr.(reflect.Value) 11 if !ok { 12 v = reflect.ValueOf(funcVarPtr) 13 } 14 15 v = reflect.Indirect(v) 16 17 if v.Kind() != reflect.Func { 18 panic("funcVarPtr must point to a func") 19 } 20 21 v.Set(reflect.MakeFunc(v.Type(), fn)) 22 } 23 24 // Func2Value wraps a func with reflect.Value 25 func Func2Value(fun interface{}) reflect.Value { 26 v := reflect.ValueOf(fun) 27 if v.Kind() != reflect.Func { 28 panic("fun must be a func") 29 } 30 return v 31 } 32 33 // FuncInputTypes for retrieve func input types 34 func FuncInputTypes(fun interface{}) (result []reflect.Type) { 35 fv, ok := fun.(reflect.Value) 36 if !ok { 37 fv = reflect.ValueOf(fun) 38 } 39 40 if fv.Kind() != reflect.Func { 41 panic("fun must be a func") 42 } 43 44 tp := fv.Type() 45 n := tp.NumIn() 46 for i := 0; i < n; i++ { 47 result = append(result, tp.In(i)) 48 } 49 50 return 51 } 52 53 // FuncOutputTypes for retrieve func output types 54 func FuncOutputTypes(fun interface{}) (result []reflect.Type) { 55 fv, ok := fun.(reflect.Value) 56 if !ok { 57 fv = reflect.ValueOf(fun) 58 } 59 60 if fv.Kind() != reflect.Func { 61 panic("fun must be a func") 62 } 63 64 tp := fv.Type() 65 n := tp.NumOut() 66 for i := 0; i < n; i++ { 67 result = append(result, tp.Out(i)) 68 } 69 70 return 71 } 72 73 // TypeByPointer for retrieve reflect.Type by a pointer value 74 func TypeByPointer(tp interface{}) reflect.Type { 75 return reflect.TypeOf(tp).Elem() 76 } 77 78 // InstanceByType returns a instance of reflect.Type wrapped in interface{} 79 func InstanceByType(t reflect.Type) interface{} { 80 return reflect.New(t).Elem().Interface() 81 } 82 83 // InstancePtrByType returns a pointer to instance 84 func InstancePtrByType(t reflect.Type) interface{} { 85 return reflect.New(t).Interface() 86 } 87 88 // InstancePtrByClone creates an instance ptr by clone 89 func InstancePtrByClone(v reflect.Value) interface{} { 90 cv := reflect.New(v.Type()) 91 cv.Elem().Set(v) 92 return cv.Interface() 93 } 94 95 // StructFieldValues for manipulate field values 96 func StructFieldValues(s interface{}, filter func(name string, f reflect.Value) bool) (fields map[string]reflect.Value) { 97 v, ok := s.(reflect.Value) 98 if !ok { 99 v = reflect.ValueOf(s) 100 } 101 v = reflect.Indirect(v) 102 103 fields = make(map[string]reflect.Value) 104 t := v.Type() 105 count := v.NumField() 106 for i := 0; i < count; i++ { 107 field := v.Field(i) 108 name := t.Field(i).Name 109 if filter == nil { 110 fields[name] = field 111 } else if filter(name, field) { 112 fields[name] = field 113 } 114 } 115 116 return 117 } 118 119 // StructFields for general struct field info 120 func StructFields(s interface{}) (fields []reflect.StructField) { 121 v, ok := s.(reflect.Value) 122 if !ok { 123 v = reflect.ValueOf(s) 124 } 125 v = reflect.Indirect(v) 126 127 t := v.Type() 128 count := v.NumField() 129 for i := 0; i < count; i++ { 130 field := t.Field(i) 131 fields = append(fields, field) 132 } 133 134 return 135 } 136 137 // ScanMethods for scan methods of s 138 func ScanMethods(s interface{}) (methods map[string]reflect.Value) { 139 v, ok := s.(reflect.Value) 140 if !ok { 141 v = reflect.ValueOf(s) 142 } 143 144 methods = make(map[string]reflect.Value) 145 t := v.Type() 146 count := v.NumMethod() 147 for i := 0; i < count; i++ { 148 methods[t.Method(i).Name] = v.Method(i) 149 } 150 151 return 152 }