5

I want to copy an array but the copied array always makes changes to the original array as well. Why is this the case?

Below is a code example of the issue:

package main

import (
    "fmt"
)

func main() {
    array := make([]int, 2)
    for i := range array {
        array[i] = 0
    }

    oldArray := array
    array[0] = 3 // why does this also change oldArray?
    oldArray[1] = 2 // why does this also change the original array?

    fmt.Println(oldArray, array)
    // I expected [0,2], [3,0]
    // but it returns [3,2], [3,2]

}

I tried to initiate the variable oldArray before array but the result is the same.

13
  • 2
    In most languages when you assign one array variable to another you're just assigning the reference and you're NOT copying the contents of the array. You're just making two variables that point to the same array. Commented Mar 11, 2021 at 5:41
  • @Enigmativity , Thank you very much for your information. Because usually I write in PHP and as I remembered on JS too, will just copying content. Commented Mar 11, 2021 at 5:45
  • 1
    array := make([]int, 2) does not create an array. It creates a slice. Commented Mar 11, 2021 at 7:07
  • 4
    @Enigmativity I hope this isn't taken as an offense, but it seems that you're "guessing" about Go (based on your tag history) and probably giving people the wrong idea. Go is a pass-by-copy language, even for arrays. Your comment is incidentally true because the asker is not using "arrays", but a data type called a slice, which by definition is a reference to an array. Commented Mar 11, 2021 at 8:58
  • 1
    @HymnsForDisco - No offence taken whatsoever. I was making an assumption. Indeed I didn't even make an assertion about Go. Commented Mar 11, 2021 at 11:19

2 Answers 2

14

In your example code, you're working with slices, not arrays.

From the slice documentation:

A slice is a descriptor for a contiguous segment of an underlying array and provides access to a numbered sequence of elements from that array.

When you assign a slice to a variable, you're creating a copy of that descriptor and therefore dealing with the same underlying array. When you're actually working with arrays, it has the behavior you're expecting.

Another snippet from the slice documentation (emphasis mine):

A slice, once initialized, is always associated with an underlying array that holds its elements. A slice therefore shares storage with its array and with other slices of the same array; by contrast, distinct arrays always represent distinct storage.

Here's a code sample (for the slices, the memory address of the first element is in parentheses, to clearly point out when two slices are using the same underlying array):

package main

import (
    "fmt"
)

func main() {
    // Arrays
    var array [2]int
    newArray := array
    array[0] = 3
    newArray[1] = 2
    fmt.Printf("Arrays:\narray: %v\nnewArray: %v\n\n", array, newArray)

    // Slices (using copy())
    slice := make([]int, 2)
    newSlice := make([]int, len(slice))
    copy(newSlice, slice)
    slice[0] = 3
    newSlice[1] = 2
    fmt.Printf("Slices (different arrays):\nslice (%p): %v \nnewSlice (%p): %v\n\n", slice, slice, newSlice, newSlice)

    // Slices (same underlying array)
    slice2 := make([]int, 2)
    newSlice2 := slice2
    slice2[0] = 3
    newSlice2[1] = 2
    fmt.Printf("Slices (same array):\nslice2 (%p): %v \nnewSlice2 (%p): %v\n\n", slice2, slice2, newSlice2, newSlice2)
}

Output:

Arrays:
array: [3 0]
newArray: [0 2]

Slices (different arrays):
slice (0xc000100040): [3 0] 
newSlice (0xc000100050): [0 2]

Slices (same array):
slice2 (0xc000100080): [3 2] 
newSlice2 (0xc000100080): [3 2]

Go Playground

Sign up to request clarification or add additional context in comments.

1 Comment

to a beginner reading that far, It might also get more subtle: play.golang.org/p/kbVvThLjaGf
4

use copy function.

oldArray := make([]int, len(array))
copy(oldArray, array)

https://play.golang.org/p/DsLJ2PDIy_N

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.