Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

There are cases we cannot deepcopy #28

Open
HarutakaMatsumoto opened this issue Oct 13, 2021 · 7 comments
Open

There are cases we cannot deepcopy #28

HarutakaMatsumoto opened this issue Oct 13, 2021 · 7 comments

Comments

@HarutakaMatsumoto
Copy link

HarutakaMatsumoto commented Oct 13, 2021

Hello!

Somehow Copy function cannot deepcopy an array of list of list.
A example test is following.

package deepcopytest

import (
	"testing"

	"github.com/mohae/deepcopy"
)

type a [3][][]float64

var source = a{
	{
		{
			1.0,
			2.0,
			3.0,
		},
	},
}

func TestDeepcopy(t *testing.T) {
	distination := deepcopy.Copy(source).(a)
	source[0][0][0] = 4.0
	source[0][0][1] = 5.0
	source[0][0][2] = 6.0

	if distination[0][0][0] == source[0][0][0] {
		t.Fatal("Isn't deepcopied!", distination, source)
	}
}

Please make it can deepcopy.
Thank you.

@dolmen
Copy link

dolmen commented Feb 2, 2022

Here is a live demo on the Go playground with a simplified test case: type [1][]int.

@DenisYin66
Copy link

`
case reflect.Array:
nv := reflect.New(original.Type())
arrCopyValue := nv.Elem()
num := original.Len()

	for i := 0; i < num; i++ {
		itemValue := original.Index(i)
		copyValue := reflect.New(itemValue.Type()).Elem()
		copyRecursive(original.Index(i), copyValue)
		arrCopyValue.Index(i).Set(copyValue)
	}

	cpy.Set(arrCopyValue)

`

@xieyuschen
Copy link

xieyuschen commented Aug 1, 2023

The author treats the array behavior wrongly, which relies on its deep copy entirely. Any reference type array will be affected by this case. Here are more test cases.
@HarutakaMatsumoto I will try to create a fix recently.

func TestArrayOfSomething(t *testing.T) {
	verifyCases := map[string]struct {
		modifyAndVerify func(t *testing.T)
	}{
		// failed because the map(underlying is a pointer) will be copied directly
		"array of map": {
			modifyAndVerify: func(t *testing.T) {
				origin := [1]map[string]int{
					{
						"1": 1,
					},
				}
				copied := deepcopy.Copy(&origin)
				assert.NotSame(t, origin, copied)
				assert.NotSame(t, origin[0], copied.(*[1]map[string]int)[0])
				origin[0]["1"] = 999
				assert.Equal(t, 1, copied.(*[1]map[string]int)[0]["1"])
			},
		},
		// failed because the pointer of map will be copied directly
		"array of *map": {
			modifyAndVerify: func(t *testing.T) {
				origin := [1]*map[string]int{
					{
						"1": 1,
					},
				}
				copied := deepcopy.Copy(&origin)
				assert.NotSame(t, origin, copied)
				assert.NotSame(t, origin[0], copied.(*[1]*map[string]int)[0])
				(*origin[0])["1"] = 999
				assert.Equal(t, 1, (*copied.(*[1]*map[string]int)[0])["1"])
			},
		},
		// failed because the pointer of int will be copied directly
		"array of *int": {
			modifyAndVerify: func(t *testing.T) {
				intp := func(i int) *int {
					return &i
				}
				arrayOfInt := [3]*int{intp(1), intp(2)}
				copied := deepcopy.Copy(&arrayOfInt)
				assert.NotSame(t, &arrayOfInt, copied)
				assert.NotSame(t, arrayOfInt[0], copied.(*[3]*int)[0])
				arrayOfInt[0] = intp(999)
				assert.Equal(t, 1, *copied.(*[3]*int)[0])
			},
		},
		// succeed because int will be copied by value
		"array of int": {
			modifyAndVerify: func(t *testing.T) {
				arrayOfInt := [3]int{1, 2}
				copied := deepcopy.Copy(&arrayOfInt)
				assert.NotSame(t, &arrayOfInt, copied)
				assert.NotSame(t, &arrayOfInt[0], copied.(*[3]int)[0])
				arrayOfInt[0] = 999
				assert.Equal(t, 1, copied.(*[3]int)[0])
			},
		},
	}
	for key, tt := range verifyCases {
		t.Run(key, tt.modifyAndVerify)
	}
}

@HarutakaMatsumoto
Copy link
Author

Hello @xieyuschen .
Oh! Thank you for your fixing!
I try to use it.

@HarutakaMatsumoto
Copy link
Author

@xieyuschen, it's been a while.
Well, I tried using github.com/xieyuschen/deepcopy and it solved this problem. Thank you!
I've been using this new repository since then, but I noticed that it was deleted.
Why did you delete it?
Could you please restore it?
Because this is so useful!

@xieyuschen
Copy link

@xieyuschen, it's been a while. Well, I tried using github.com/xieyuschen/deepcopy and it solved this problem. Thank you! I've been using this new repository since then, but I noticed that it was deleted. Why did you delete it? Could you please restore it? Because this is so useful!

@HarutakaMatsumoto restored:)

@HarutakaMatsumoto
Copy link
Author

@xieyuschen
Thank you very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants