github.com/andeya/ameda@v1.5.3/initialize.go (about) 1 package ameda 2 3 import ( 4 "reflect" 5 ) 6 7 // InitPointer initializes nil pointer with zero value. 8 func InitPointer(v reflect.Value) (done bool) { 9 for { 10 kind := v.Kind() 11 if kind == reflect.Interface { 12 v = v.Elem() 13 continue 14 } 15 if kind != reflect.Ptr { 16 return true 17 } 18 u := v.Elem() 19 if u.IsValid() { 20 v = u 21 continue 22 } 23 if !v.CanSet() { 24 return false 25 } 26 v2 := reflect.New(v.Type().Elem()) 27 v.Set(v2) 28 v = v.Elem() 29 } 30 } 31 32 // InitString initializes empty string pointer with def. 33 func InitString(p *string, def string) (done bool) { 34 if p == nil { 35 return false 36 } 37 if *p == "" { 38 *p = def 39 } 40 return true 41 } 42 43 // InitBool initializes false bool pointer with def. 44 func InitBool(p *bool, def bool) (done bool) { 45 if p == nil { 46 return false 47 } 48 if *p == false { 49 *p = def 50 } 51 return true 52 } 53 54 // InitByte initializes zero byte pointer with def. 55 func InitByte(p *byte, def byte) (done bool) { 56 if p == nil { 57 return false 58 } 59 if *p == 0 { 60 *p = def 61 } 62 return true 63 } 64 65 // InitInt initializes zero int pointer with def. 66 func InitInt(p *int, def int) (done bool) { 67 if p == nil { 68 return false 69 } 70 if *p == 0 { 71 *p = def 72 } 73 return true 74 } 75 76 // InitInt8 initializes zero int8 pointer with def. 77 func InitInt8(p *int8, def int8) (done bool) { 78 if p == nil { 79 return false 80 } 81 if *p == 0 { 82 *p = def 83 } 84 return true 85 } 86 87 // InitInt16 initializes zero int16 pointer with def. 88 func InitInt16(p *int16, def int16) (done bool) { 89 if p == nil { 90 return false 91 } 92 if *p == 0 { 93 *p = def 94 } 95 return true 96 } 97 98 // InitInt32 initializes zero int32 pointer with def. 99 func InitInt32(p *int32, def int32) (done bool) { 100 if p == nil { 101 return false 102 } 103 if *p == 0 { 104 *p = def 105 } 106 return true 107 } 108 109 // InitInt64 initializes zero int64 pointer with def. 110 func InitInt64(p *int64, def int64) (done bool) { 111 if p == nil { 112 return false 113 } 114 if *p == 0 { 115 *p = def 116 } 117 return true 118 } 119 120 // InitUint initializes zero uint pointer with def. 121 func InitUint(p *uint, def uint) (done bool) { 122 if p == nil { 123 return false 124 } 125 if *p == 0 { 126 *p = def 127 } 128 return true 129 } 130 131 // InitUint8 initializes zero uint8 pointer with def. 132 func InitUint8(p *uint8, def uint8) (done bool) { 133 if p == nil { 134 return false 135 } 136 if *p == 0 { 137 *p = def 138 } 139 return true 140 } 141 142 // InitUint16 initializes zero uint16 pointer with def. 143 func InitUint16(p *uint16, def uint16) (done bool) { 144 if p == nil { 145 return false 146 } 147 if *p == 0 { 148 *p = def 149 } 150 return true 151 } 152 153 // InitUint32 initializes zero uint32 pointer with def. 154 func InitUint32(p *uint32, def uint32) (done bool) { 155 if p == nil { 156 return false 157 } 158 if *p == 0 { 159 *p = def 160 } 161 return true 162 } 163 164 // InitUint64 initializes zero uint64 pointer with def. 165 func InitUint64(p *uint64, def uint64) (done bool) { 166 if p == nil { 167 return false 168 } 169 if *p == 0 { 170 *p = def 171 } 172 return true 173 } 174 175 // InitFloat32 initializes zero float32 pointer with def. 176 func InitFloat32(p *float32, def float32) (done bool) { 177 if p == nil { 178 return false 179 } 180 if *p == 0 { 181 *p = def 182 } 183 return true 184 } 185 186 // InitFloat64 initializes zero float64 pointer with def. 187 func InitFloat64(p *float64, def float64) (done bool) { 188 if p == nil { 189 return false 190 } 191 if *p == 0 { 192 *p = def 193 } 194 return true 195 } 196 197 // InitSampleValue initialize the given type with some non-zero value( "?", $max_number, 0.1, true) 198 func InitSampleValue(t reflect.Type, maxNestingDeep int) reflect.Value { 199 if maxNestingDeep <= 0 { 200 maxNestingDeep = 10 201 } 202 ptrDepth := 0 203 for t.Kind() == reflect.Ptr { 204 t = t.Elem() 205 ptrDepth++ 206 } 207 v := reflect.New(t) 208 v = initValue(v, 1, maxNestingDeep) 209 return ReferenceValue(v, ptrDepth-1) 210 } 211 212 func initValue(v reflect.Value, curDeep int, maxDeep int) reflect.Value { 213 InitPointer(v) 214 if curDeep >= maxDeep { 215 return v 216 } 217 var numPtr int 218 for v.Kind() == reflect.Ptr { 219 v = v.Elem() 220 numPtr++ 221 } 222 if v.CanSet() { 223 switch v.Kind() { 224 case reflect.Struct: 225 curDeep++ 226 fieldNum := v.Type().NumField() 227 for i := 0; i < fieldNum; i++ { 228 e := v.Field(i) 229 InitPointer(e) 230 if e.CanSet() { 231 e.Set(initValue(e, curDeep, maxDeep)) 232 } 233 } 234 case reflect.Slice: 235 if v.Len() == 0 { 236 e := reflect.New(v.Type().Elem()) 237 InitPointer(e) 238 e = e.Elem() 239 e = initValue(e, curDeep, maxDeep) 240 if v.CanSet() { 241 v.Set(reflect.Append(v, e)) 242 } 243 } 244 case reflect.Array: 245 if v.Len() > 0 { 246 e := reflect.New(v.Type().Elem()) 247 InitPointer(e) 248 e = e.Elem() 249 e = initValue(e, curDeep, maxDeep) 250 vv := v.Index(0) 251 if vv.CanSet() { 252 vv.Set(reflect.Append(v, e)) 253 } 254 } 255 case reflect.Map: 256 if v.Len() == 0 { 257 v.Set(reflect.MakeMap(v.Type())) 258 k := reflect.New(v.Type().Key()) 259 InitPointer(k) 260 k = k.Elem() 261 k = initValue(k, curDeep, maxDeep) 262 e := reflect.New(v.Type().Elem()) 263 InitPointer(e) 264 e = e.Elem() 265 e = initValue(e, curDeep, maxDeep) 266 v.SetMapIndex(k, e) 267 } 268 case reflect.Int: 269 if Host32bit { 270 v.SetInt(-32) 271 } else { 272 v.SetInt(-64) 273 } 274 case reflect.Int8: 275 v.SetInt(-8) 276 case reflect.Int16: 277 v.SetInt(-16) 278 case reflect.Int32: 279 v.SetInt(-32) 280 case reflect.Int64: 281 v.SetInt(-64) 282 case reflect.Uint, reflect.Uintptr: 283 if Host32bit { 284 v.SetUint(32) 285 } else { 286 v.SetUint(64) 287 } 288 case reflect.Uint8: 289 v.SetUint(8) 290 case reflect.Uint16: 291 v.SetUint(16) 292 case reflect.Uint32: 293 v.SetUint(32) 294 case reflect.Uint64: 295 v.SetUint(64) 296 case reflect.Float32: 297 v.SetFloat(-0.32) 298 case reflect.Float64: 299 v.SetFloat(-0.64) 300 case reflect.Bool: 301 v.SetBool(true) 302 case reflect.String: 303 v.SetString("?") 304 default: 305 } 306 } 307 return ReferenceValue(v, numPtr) 308 }