gitee.com/quant1x/gox@v1.7.6/api/reflect_array.go (about)

     1  package api
     2  
     3  import (
     4  	"gitee.com/quant1x/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  // Convert 将字符串数组按照下标的序号反射给一个结构体
    46  func Convert[T any](data []string, v *T) error {
    47  	obj := reflect.ValueOf(v)
    48  	t := obj.Type()
    49  	if obj.Kind() == reflect.Ptr {
    50  		t = t.Elem()
    51  		obj = obj.Elem()
    52  	}
    53  	ma := initTag(t)
    54  	if ma == nil {
    55  		return errors.New("can not Convert")
    56  	}
    57  	//fieldNum := t.NumField()
    58  	fieldNum := len(data)
    59  	for i := 0; i < fieldNum; i++ {
    60  		field, ok := ma[i]
    61  		if ok {
    62  			dv := data[i]
    63  			ov := obj.FieldByName(field.Name)
    64  			if ov.CanSet() {
    65  				var value interface{}
    66  				switch ov.Interface().(type) {
    67  				case string:
    68  					value = dv
    69  				case int8:
    70  					t := ParseInt(dv)
    71  					value = int8(t)
    72  				case int16:
    73  					t := ParseInt(dv)
    74  					value = int16(t)
    75  				case int32:
    76  					t := ParseInt(dv)
    77  					value = int32(t)
    78  				case int64:
    79  					t := ParseInt(dv)
    80  					value = int64(t)
    81  				case uint8:
    82  					t := ParseUint(dv)
    83  					value = uint8(t)
    84  				case uint16:
    85  					t := ParseUint(dv)
    86  					value = uint16(t)
    87  				case uint32:
    88  					t := ParseUint(dv)
    89  					value = uint32(t)
    90  				case uint64:
    91  					t := ParseUint(dv)
    92  					value = t
    93  				case float32:
    94  					t := ParseFloat(dv)
    95  					value = float32(t)
    96  				case float64:
    97  					t := ParseFloat(dv)
    98  					value = t
    99  				case bool:
   100  					t, _ := strconv.ParseBool(dv)
   101  					value = t
   102  				default:
   103  					value = dv
   104  				}
   105  				ov.Set(reflect.ValueOf(value))
   106  			}
   107  		}
   108  	}
   109  	return nil
   110  }