github.com/mymmsc/gox@v1.3.33/api/reflect_array.go (about) 1 package api 2 3 import ( 4 "github.com/mymmsc/gox/errors" 5 "reflect" 6 "strconv" 7 ) 8 9 var ( 10 // 结构体 tag array的反射的字段缓存 11 __mapTagArray map[reflect.Type]map[int]reflect.StructField = nil 12 ) 13 14 func init() { 15 __mapTagArray = make(map[reflect.Type]map[int]reflect.StructField) 16 } 17 18 func initTag(t reflect.Type) map[int]reflect.StructField { 19 ma, mok := __mapTagArray[t] 20 if mok { 21 return ma 22 } 23 ma = nil 24 fieldNum := t.NumField() 25 for i := 0; i < fieldNum; i++ { 26 field := t.Field(i) 27 tag := field.Tag 28 if len(tag) > 0 { 29 tv, ok := tag.Lookup("array") 30 if ok { 31 index, err := strconv.Atoi(tv) 32 if err == nil { 33 if ma == nil { 34 ma = make(map[int]reflect.StructField) 35 __mapTagArray[t] = ma 36 } 37 ma[index] = field 38 } 39 } 40 } 41 } 42 return ma 43 } 44 45 func Convert(data []string, v interface{}) error { 46 val := reflect.ValueOf(v) 47 //t := reflect.TypeOf(v) 48 //fieldNum := val.NumField() 49 //_ = fieldNum 50 obj := reflect.ValueOf(v) 51 t := val.Type() 52 if val.Kind() == reflect.Ptr { 53 t = t.Elem() 54 obj = obj.Elem() 55 } 56 ma := initTag(t) 57 if ma == nil { 58 return errors.New("can not Convert") 59 } 60 dl := len(data) 61 for i := 0; i < dl; i++ { 62 field, ok := ma[i] 63 if ok { 64 dv := data[i] 65 ov := obj.FieldByName(field.Name) 66 if ov.CanSet() { 67 var value interface{} 68 switch ov.Interface().(type) { 69 case string: 70 value = string(dv) 71 case int8: 72 t := ParseInt(dv) 73 value = int8(t) 74 case int16: 75 t := ParseInt(dv) 76 value = int16(t) 77 case int32: 78 t := ParseInt(dv) 79 value = int32(t) 80 case int64: 81 t := ParseInt(dv) 82 value = int64(t) 83 case uint8: 84 t := ParseUint(dv) 85 value = uint8(t) 86 case uint16: 87 t := ParseUint(dv) 88 value = uint16(t) 89 case uint32: 90 t := ParseUint(dv) 91 value = uint32(t) 92 case uint64: 93 t := ParseUint(dv) 94 value = t 95 case float32: 96 t := ParseFloat(dv) 97 value = float32(t) 98 case float64: 99 t := ParseFloat(dv) 100 value = t 101 case bool: 102 t, _ := strconv.ParseBool(dv) 103 value = t 104 default: 105 value = dv 106 } 107 ov.Set(reflect.ValueOf(value)) 108 } 109 } 110 } 111 return nil 112 }