🧑‍🤝‍🧑 Copy a slice in Go

introduction slice

To duplicate a slice in Go, getting a deep copy of its contents, you need to either use the built-in copy() function, or create a new empty slice and add all the elements of the first slice to it using the append() function. Because of how slices are built in Go, assigning one slice to another only makes a shallow copy, and you should not use it if you want to clone the slice in a deep way.

Copy a slice using the copy() function

package main

import "fmt"

func main() {
    src := []string{"a", "b", "c"}
    dst := make([]string, len(src))

    copy(dst, src)

    fmt.Printf("source slice: %[1]v, address: %[1]p\n", src)
    fmt.Printf("source slice: %[1]v, address: %[1]p\n", dst)
}

Output:

source slice: [a b c], address: 0xc000098180
source slice: [a b c], address: 0xc0000981b0

As you can see, we got two different addresses of underlying arrays for the src and dst slices, which is evidence that we deeply cloned the src slice. The copy() function copies min(len(dst), len(src)) elements, so we need to create the dst slice of the same size as the src using make([]string, len(src)).

Copy a slice using the append() function

package main

import "fmt"

func main() {
    src := []string{"a", "b", "c"}
    var dst []string

    dst = append(dst, src...)

    fmt.Printf("source slice: %[1]v, address: %[1]p\n", src)
    fmt.Printf("source slice: %[1]v, address: %[1]p\n", dst)
}

Output:

source slice: [a b c], address: 0xc000098180
source slice: [a b c], address: 0xc0000981b0

Copying a slice using the append() function is really simple. You just need to define a new empty slice, and use the append() to add all elements of the src to the dst slice. In that way, you get a new slice with all the elements duplicated.

Shallow copy by assignment

package main

import "fmt"

func main() {
    src := []string{"a", "b", "c"}
    dst := src

    fmt.Printf("source slice: %[1]v, address: %[1]p\n", src)
    fmt.Printf("source slice: %[1]v, address: %[1]p\n", dst)
}

Output:

source slice: [a b c], address: 0xc000098180
source slice: [a b c], address: 0xc000098180

If you just assign the src slice to the new dst variable, you get a shallow copy that has the same underlying array. When you modify the contents of this copy, the original slice will also change.

🔎 Check if the slice contains the given value in Go

Learn how to write a function that checks if a slice has a specific value
introduction slice

🖨️ Convert string to []byte or []byte to string in Go

Learn the difference between a string and a byte slice
introduction strings slice

🧠 Print the memory address of a variable in Go

Learn how to find and print the address of a variable or pointer
introduction pointer slice