github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/f/reflect.go (about) 1 package f 2 3 import ( 4 "fmt" 5 "math" 6 "reflect" 7 ) 8 9 /************************************************************* 10 * Reflection: 11 * From package(go 1.13) "reflect" -> reflect/value.go 12 *************************************************************/ 13 14 // IsZero reports whether v is the zero value for its type. 15 // It panics if the argument is invalid. 16 // NOTICE: this's an built-in method in reflect/value.go since go 1.13 17 func IsZero(v reflect.Value) bool { 18 switch v.Kind() { 19 case reflect.Bool: 20 return !v.Bool() 21 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 22 return v.Int() == 0 23 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 24 return v.Uint() == 0 25 case reflect.Float32, reflect.Float64: 26 return math.Float64bits(v.Float()) == 0 27 case reflect.Complex64, reflect.Complex128: 28 c := v.Complex() 29 return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0 30 case reflect.Array: 31 for i := 0; i < v.Len(); i++ { 32 // if !v.Index(i).IsZero() { 33 if !IsZero(v.Index(i)) { 34 return false 35 } 36 } 37 return true 38 case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer: 39 return v.IsNil() 40 case reflect.String: 41 return v.Len() == 0 42 case reflect.Struct: 43 for i := 0; i < v.NumField(); i++ { 44 // if !v.Index(i).IsZero() { 45 if !IsZero(v.Field(i)) { 46 return false 47 } 48 } 49 return true 50 default: 51 // This should never happens, but will act as a safeguard for 52 // later, as a default value doesn't makes sense here. 53 panic(&reflect.ValueError{Method: "cannot check reflect.Value.IsZero", Kind: v.Kind()}) 54 } 55 } 56 57 // IsEmpty Is the variable empty. 58 func IsEmpty(val interface{}) bool { 59 if val == nil { 60 return true 61 } 62 63 v := reflect.ValueOf(val) 64 switch v.Kind() { 65 case reflect.String, reflect.Array, reflect.Chan: 66 return v.Len() == 0 67 case reflect.Map, reflect.Slice: 68 return v.Len() == 0 || v.IsNil() 69 case reflect.Bool: 70 return !v.Bool() 71 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 72 return v.Int() == 0 73 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 74 return v.Uint() == 0 75 case reflect.Float32, reflect.Float64: 76 return v.Float() == 0 77 case reflect.Interface, reflect.Ptr: 78 if v.IsNil() { 79 return true 80 } 81 return IsEmpty(v.Elem().Interface()) 82 } 83 84 return reflect.DeepEqual(val, reflect.Zero(v.Type()).Interface()) 85 } 86 87 // IsNil checks if a specified object is nil or not, without Failing. 88 func IsNil(object interface{}) bool { 89 if object == nil { 90 return true 91 } 92 93 value := reflect.ValueOf(object) 94 kind := value.Kind() 95 isNilKind := containsKind( 96 []reflect.Kind{ 97 reflect.Chan, reflect.Func, 98 reflect.Interface, reflect.Map, 99 reflect.Ptr, reflect.Slice}, 100 kind) 101 102 if isNilKind && value.IsNil() { 103 return true 104 } 105 106 return false 107 } 108 109 // Eq evaluates the comparison a == b 110 // Support: 111 // bool, int(X), uint(X), string, float(X) 112 func Eq(arg1 reflect.Value, arg2 reflect.Value) (bool, error) { 113 v1 := indirectInterface(arg1) 114 k1, err := basicKind(v1) 115 if err != nil { 116 return false, err 117 } 118 119 v2 := indirectInterface(arg2) 120 k2, err := basicKind(v2) 121 if err != nil { 122 return false, err 123 } 124 125 truth := false 126 if k1 != k2 { 127 // Special case: Can compare integer values regardless of type's sign. 128 switch { 129 case k1 == intKind && k2 == uintKind: 130 truth = v1.Int() >= 0 && uint64(v1.Int()) == v2.Uint() 131 case k1 == uintKind && k2 == intKind: 132 truth = v2.Int() >= 0 && v1.Uint() == uint64(v2.Int()) 133 } 134 return truth, nil 135 } 136 137 switch k1 { 138 case boolKind: 139 truth = v1.Bool() == v2.Bool() 140 case complexKind: 141 truth = v1.Complex() == v2.Complex() 142 case floatKind: 143 truth = v1.Float() == v2.Float() 144 case intKind: 145 truth = v1.Int() == v2.Int() 146 case stringKind: 147 truth = v1.String() == v2.String() 148 case uintKind: 149 truth = v1.Uint() == v2.Uint() 150 } 151 152 return truth, nil 153 } 154 155 // ValueLen returns v's length. 156 func ValueLen(v reflect.Value) int { 157 k := v.Kind() 158 159 // (u)int use width. 160 switch k { 161 case reflect.Map, reflect.Array, reflect.Chan, reflect.Slice, reflect.String: 162 return v.Len() 163 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 164 return len(fmt.Sprint(v.Uint())) 165 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 166 return len(fmt.Sprint(v.Int())) 167 case reflect.Float32, reflect.Float64: 168 return len(fmt.Sprint(v.Interface())) 169 } 170 171 // cannot get length 172 return -1 173 } 174 175 // TypeElem returns the underlying type if the given type is a pointer. 176 func TypeElem(t reflect.Type) reflect.Type { 177 for t != nil && t.Kind() == reflect.Ptr { 178 t = t.Elem() 179 } 180 return t 181 } 182 183 /************************************************************* 184 * Reflection Kind Extensions 185 *************************************************************/ 186 187 type kind int 188 189 const ( 190 invalidKind kind = iota 191 boolKind 192 complexKind 193 intKind 194 floatKind 195 stringKind 196 uintKind 197 ) 198 199 func basicKind(v reflect.Value) (kind, error) { 200 switch v.Kind() { 201 case reflect.Bool: 202 return boolKind, nil 203 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 204 return intKind, nil 205 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 206 return uintKind, nil 207 case reflect.Float32, reflect.Float64: 208 return floatKind, nil 209 case reflect.Complex64, reflect.Complex128: 210 return complexKind, nil 211 case reflect.String: 212 return stringKind, nil 213 } 214 215 // like: slice, array, map ... 216 return invalidKind, ErrBadComparisonType 217 } 218 219 // indirectInterface returns the concrete value in an interface value, 220 // or else the zero reflect.Value. 221 // That is, if v represents the interface value x, the result is the same as reflect.ValueOf(x): 222 // the fact that x was an interface value is forgotten. 223 func indirectInterface(v reflect.Value) reflect.Value { 224 if v.Kind() != reflect.Interface { 225 return v 226 } 227 228 if v.IsNil() { 229 return emptyValue 230 } 231 232 return v.Elem() 233 } 234 235 // containsKind checks if a specified kind in the slice of kinds. 236 func containsKind(kinds []reflect.Kind, kind reflect.Kind) bool { 237 for i := 0; i < len(kinds); i++ { 238 if kind == kinds[i] { 239 return true 240 } 241 } 242 243 return false 244 }