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  }