QRM skip unnecessary new slice element copying.

This commit is contained in:
go-jet 2021-10-21 13:28:01 +02:00
parent 51cad22809
commit 6080ae134f

View file

@ -55,7 +55,14 @@ func appendElemToSlice(slicePtrValue reflect.Value, objPtrValue reflect.Value) e
sliceValue := slicePtrValue.Elem()
sliceElemType := sliceValue.Type().Elem()
newSliceElemValue := reflect.New(sliceElemType).Elem()
var newSliceElemValue reflect.Value
if objPtrValue.Type().AssignableTo(sliceElemType) {
newSliceElemValue = objPtrValue
} else if objPtrValue.Elem().Type().AssignableTo(sliceElemType) {
newSliceElemValue = objPtrValue.Elem()
} else {
newSliceElemValue = reflect.New(sliceElemType).Elem()
var err error
@ -69,6 +76,7 @@ func appendElemToSlice(slicePtrValue reflect.Value, objPtrValue reflect.Value) e
if err != nil {
return fmt.Errorf("can't append %T to %T slice: %w", objPtrValue.Elem().Interface(), sliceValue.Interface(), err)
}
}
sliceValue.Set(reflect.Append(sliceValue, newSliceElemValue))
@ -172,6 +180,18 @@ func isSimpleModelType(objType reflect.Type) bool {
return objType == timeType || objType == uuidType || objType == byteArrayType
}
func isIntegerType(objType reflect.Type) bool {
objType = indirectType(objType)
switch objType.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return true
}
return false
}
func isFloatType(value reflect.Type) bool {
switch value.Kind() {
case reflect.Float32, reflect.Float64:
@ -185,6 +205,7 @@ func tryAssign(source, destination reflect.Value) error {
if source.Type() != destination.Type() &&
!isFloatType(destination.Type()) && // to preserve precision during conversion
!(isIntegerType(source.Type()) && destination.Kind() == reflect.String) && // default conversion will convert int to 1 rune string
source.Type().ConvertibleTo(destination.Type()) {
source = source.Convert(destination.Type())