func ConvertSliceValueType()

in codec.go [481:532]


func ConvertSliceValueType(destTyp reflect.Type, v reflect.Value) (reflect.Value, error) {
	if destTyp == v.Type() || destTyp.Kind() == reflect.Interface {
		return v, nil
	}

	k := v.Type().Kind()
	if k != reflect.Slice && k != reflect.Array {
		return _zeroValue, perrors.Errorf("expect slice type, but get %v, objects: %v", k, v)
	}

	if v.Len() <= 0 {
		return _zeroValue, nil
	}

	elemKind := destTyp.Elem().Kind()
	elemPtrType := elemKind == reflect.Ptr
	elemFloatType := validateFloatKind(elemKind)
	elemIntType := validateIntKind(elemKind)
	elemUintType := validateUintKind(elemKind)

	sl := reflect.MakeSlice(destTyp, v.Len(), v.Len())
	var itemValue reflect.Value
	for i := 0; i < v.Len(); i++ {
		item := v.Index(i).Interface()
		if cv, ok := item.(reflect.Value); ok {
			itemValue = cv
		} else {
			if item == nil {
				itemValue = reflect.Zero(destTyp.Elem())
			} else {
				itemValue = reflect.ValueOf(item)
			}
		}

		if !elemPtrType && itemValue.Kind() == reflect.Ptr {
			itemValue = UnpackPtrValue(itemValue)
		}

		switch {
		case elemFloatType:
			sl.Index(i).SetFloat(itemValue.Float())
		case elemIntType:
			sl.Index(i).SetInt(itemValue.Int())
		case elemUintType:
			sl.Index(i).SetUint(itemValue.Uint())
		default:
			SetValue(sl.Index(i), itemValue)
		}
	}

	return sl, nil
}