Deep Copy vs Shallow Copy in Go: Arrays and Slices

Table of Contents

  1. Introduction
  2. Deep Copy
  3. Shallow Copy
  4. Copying Arrays
  5. Copying Slices
  6. Conclusion

Introduction

In Go, when working with arrays and slices, it’s important to understand the difference between deep copy and shallow copy. Deep copy creates a completely separate copy of an array or slice, while shallow copy creates a new reference to the same underlying data. This tutorial will explain the concepts of deep copy and shallow copy in Go and demonstrate how to perform these operations on arrays and slices.

Before proceeding with this tutorial, it is recommended to have basic knowledge of Go syntax and concepts, including arrays and slices. Additionally, make sure you have Go installed on your system to practice the examples provided.

Deep Copy

Deep copy involves creating an entirely independent copy of the original data. Modifying the deep copy will not affect the original data. To perform a deep copy in Go, you need to manually copy each element of the array or slice.

Shallow Copy

Shallow copy, on the other hand, creates a new reference to the same underlying data. Modifying the shallow copy will affect the original data. To perform a shallow copy in Go, you can simply assign one array or slice to another.

Copying Arrays

To demonstrate the difference between deep copy and shallow copy, let’s start with copying arrays.

package main

import "fmt"

func main() {
    // Original array
    original := [3]int{1, 2, 3}

    // Deep copy
    deepCopy := original

    // Shallow copy
    shallowCopy := original

    // Modify the deep copy
    deepCopy[0] = 10

    // Modify the shallow copy
    shallowCopy[0] = 20

    fmt.Println("Original array:", original)
    fmt.Println("Deep copy:", deepCopy)
    fmt.Println("Shallow copy:", shallowCopy)
}

Output:

Original array: [1 2 3]
Deep copy: [10 2 3]
Shallow copy: [20 2 3]

In the above example, we create an original array [1 2 3]. We then make a deep copy and a shallow copy of the original array. After modifying the deep copy and shallow copy, we print the original array as well as the modified deep copy and shallow copy.

As you can see, modifying the deep copy does not affect the original array, while modifying the shallow copy changes the original array as well.

Copying Slices

Now let’s move on to copying slices, which can behave differently than arrays when it comes to copying.

package main

import "fmt"

func main() {
    // Original slice
    original := []int{1, 2, 3}

    // Deep copy
    deepCopy := make([]int, len(original))
    copy(deepCopy, original)

    // Shallow copy
    shallowCopy := original

    // Modify the deep copy
    deepCopy[0] = 10

    // Modify the shallow copy
    shallowCopy[0] = 20

    fmt.Println("Original slice:", original)
    fmt.Println("Deep copy:", deepCopy)
    fmt.Println("Shallow copy:", shallowCopy)
}

Output:

Original slice: [20 2 3]
Deep copy: [10 2 3]
Shallow copy: [20 2 3]

In the above example, we use the copy function to perform a deep copy of the original slice. We create a new slice with the same length as the original and copy each element from the original to the deep copy. We also make a shallow copy of the original slice.

After modifying the deep copy and shallow copy, we can see that modifying the deep copy does not affect the original slice, while modifying the shallow copy changes the original slice as well. However, unlike arrays, the shallow copy’s modification of the original slice is not immediate. This is because slices are references to underlying arrays, and the modification affects the shared underlying array.

Conclusion

In this tutorial, we explored the concepts of deep copy and shallow copy in Go when working with arrays and slices. We learned that deep copy creates a completely independent copy of the data, while shallow copy creates a new reference to the same underlying data.

When copying arrays, deep copy and shallow copy behave as expected. However, when copying slices, the behavior can be different due to the underlying array reference. Understanding these differences is crucial to avoid unexpected modifications to the original data.

I hope this tutorial helps you understand deep copy and shallow copy in Go and how to apply them to arrays and slices effectively. Remember to practice these concepts in your own Go programs to reinforce your learning and explore further possibilities with arrays and slices.