Skip to content

Commit

Permalink
Fix deep copy slice of interface, close jinzhu#89
Browse files Browse the repository at this point in the history
  • Loading branch information
jinzhu authored and tomtwinkle committed Mar 19, 2021
1 parent 9332070 commit 8ca2e5a
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 1 deletion.
7 changes: 6 additions & 1 deletion copier.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,12 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error)
}

if toType.Kind() == reflect.Interface {
toType = reflect.TypeOf(to.Interface())
toType, _ = indirectType(reflect.TypeOf(to.Interface()))
oldTo := to
to = reflect.New(reflect.TypeOf(to.Interface())).Elem()
defer func() {
oldTo.Set(to)
}()
}

// Just set it if possible to assign for normal types
Expand Down
30 changes: 30 additions & 0 deletions copier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package copier_test
import (
"database/sql"
"errors"
"fmt"
"testing"
"time"

Expand Down Expand Up @@ -1210,3 +1211,32 @@ func TestScanFromPtrToSqlNullable(t *testing.T) {
t.Errorf("Fields T2 fields should be equal")
}
}

func TestDeepCopyInterface(t *testing.T) {
var m = make(map[string]string)
m["a"] = "ccc"

from := []interface{}{[]int{7, 8, 9}, 2, 3, m, errors.New("aaaa")}
var to []interface{}

copier.CopyWithOption(&to, &from, copier.Option{
IgnoreEmpty: false,
DeepCopy: true,
})

from[0].([]int)[0] = 10
from[1] = "3"
from[3].(map[string]string)["a"] = "bbb"

if fmt.Sprint(to[0]) != fmt.Sprint([]int{7, 8, 9}) {
t.Errorf("to value failed to be deep copied")
}

if fmt.Sprint(to[1]) != "2" {
t.Errorf("to value failed to be deep copied")
}

if to[3].(map[string]string)["a"] != "ccc" {
t.Errorf("to value failed to be deep copied")
}
}

0 comments on commit 8ca2e5a

Please sign in to comment.