diff --git a/copier.go b/copier.go index 286ddb6..84efd25 100644 --- a/copier.go +++ b/copier.go @@ -176,26 +176,27 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error) return } - if from.Kind() == reflect.Slice && to.Kind() == reflect.Slice && fromType.ConvertibleTo(toType) { + if from.Kind() == reflect.Slice && to.Kind() == reflect.Slice { if to.IsNil() { slice := reflect.MakeSlice(reflect.SliceOf(to.Type().Elem()), from.Len(), from.Cap()) to.Set(slice) } + if fromType.ConvertibleTo(toType) { + for i := 0; i < from.Len(); i++ { + if to.Len() < i+1 { + to.Set(reflect.Append(to, reflect.New(to.Type().Elem()).Elem())) + } - for i := 0; i < from.Len(); i++ { - if to.Len() < i+1 { - to.Set(reflect.Append(to, reflect.New(to.Type().Elem()).Elem())) - } - - if !set(to.Index(i), from.Index(i), opt.DeepCopy, converters) { - // ignore error while copy slice element - err = copier(to.Index(i).Addr().Interface(), from.Index(i).Interface(), opt) - if err != nil { - continue + if !set(to.Index(i), from.Index(i), opt.DeepCopy, converters) { + // ignore error while copy slice element + err = copier(to.Index(i).Addr().Interface(), from.Index(i).Interface(), opt) + if err != nil { + continue + } } } + return } - return } if fromType.Kind() != reflect.Struct || toType.Kind() != reflect.Struct { diff --git a/copier_test.go b/copier_test.go index 4cc85b4..ec097cc 100644 --- a/copier_test.go +++ b/copier_test.go @@ -1666,3 +1666,33 @@ func TestSqlNullFiled(t *testing.T) { t.Errorf("to (%v) value should equal from (%v) value", to.MkExpiryDateType, from.MkExpiryDateType.Int32) } } + +func TestEmptySlice(t *testing.T) { + type Str1 string + type Str2 string + type Input1 struct { + Val Str1 + } + type Input2 struct { + Val Str2 + } + to := []*Input1(nil) + from := []*Input2{} + err := copier.Copy(&to, &from) + if err != nil { + t.Error("should not error") + } + if from == nil { + t.Error("from should be empty slice not nil") + } + + to = []*Input1(nil) + from = []*Input2(nil) + err = copier.Copy(&to, &from) + if err != nil { + t.Error("should not error") + } + if from != nil { + t.Error("from should be empty slice nil") + } +}