QRM skip unnecessary new slice element copying.
This commit is contained in:
parent
51cad22809
commit
6080ae134f
1 changed files with 31 additions and 10 deletions
41
qrm/utill.go
41
qrm/utill.go
|
|
@ -55,19 +55,27 @@ func appendElemToSlice(slicePtrValue reflect.Value, objPtrValue reflect.Value) e
|
||||||
sliceValue := slicePtrValue.Elem()
|
sliceValue := slicePtrValue.Elem()
|
||||||
sliceElemType := sliceValue.Type().Elem()
|
sliceElemType := sliceValue.Type().Elem()
|
||||||
|
|
||||||
newSliceElemValue := reflect.New(sliceElemType).Elem()
|
var newSliceElemValue reflect.Value
|
||||||
|
|
||||||
var err error
|
if objPtrValue.Type().AssignableTo(sliceElemType) {
|
||||||
|
newSliceElemValue = objPtrValue
|
||||||
if newSliceElemValue.Kind() == reflect.Ptr {
|
} else if objPtrValue.Elem().Type().AssignableTo(sliceElemType) {
|
||||||
newSliceElemValue.Set(reflect.New(newSliceElemValue.Type().Elem()))
|
newSliceElemValue = objPtrValue.Elem()
|
||||||
err = tryAssign(objPtrValue.Elem(), newSliceElemValue.Elem())
|
|
||||||
} else {
|
} else {
|
||||||
err = tryAssign(objPtrValue.Elem(), newSliceElemValue)
|
newSliceElemValue = reflect.New(sliceElemType).Elem()
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
var err error
|
||||||
return fmt.Errorf("can't append %T to %T slice: %w", objPtrValue.Elem().Interface(), sliceValue.Interface(), err)
|
|
||||||
|
if newSliceElemValue.Kind() == reflect.Ptr {
|
||||||
|
newSliceElemValue.Set(reflect.New(newSliceElemValue.Type().Elem()))
|
||||||
|
err = tryAssign(objPtrValue.Elem(), newSliceElemValue.Elem())
|
||||||
|
} else {
|
||||||
|
err = tryAssign(objPtrValue.Elem(), newSliceElemValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
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))
|
sliceValue.Set(reflect.Append(sliceValue, newSliceElemValue))
|
||||||
|
|
@ -172,6 +180,18 @@ func isSimpleModelType(objType reflect.Type) bool {
|
||||||
return objType == timeType || objType == uuidType || objType == byteArrayType
|
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 {
|
func isFloatType(value reflect.Type) bool {
|
||||||
switch value.Kind() {
|
switch value.Kind() {
|
||||||
case reflect.Float32, reflect.Float64:
|
case reflect.Float32, reflect.Float64:
|
||||||
|
|
@ -185,6 +205,7 @@ func tryAssign(source, destination reflect.Value) error {
|
||||||
|
|
||||||
if source.Type() != destination.Type() &&
|
if source.Type() != destination.Type() &&
|
||||||
!isFloatType(destination.Type()) && // to preserve precision during conversion
|
!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.Type().ConvertibleTo(destination.Type()) {
|
||||||
|
|
||||||
source = source.Convert(destination.Type())
|
source = source.Convert(destination.Type())
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue