W3Basic Logo

Copy a slice in Go

In Go, a slice is a lightweight data structure that provides a flexible and convenient way to work with sequences of data. However, when working with slices, it's important to understand the difference between a shallow copy and a deep copy.

What is Shallow Copy?

A shallow copy creates a new slice with a new header pointing to the same underlying array as the original slice. This means that changes made to the elements of the new slice will be reflected in the original slice and vice versa.

What is Deep Copy?

A deep copy creates a new underlying array and copies the elements of the original slice into the new array. This ensures that the original and duplicate slices are completely independent of each other.

Let us look at different ways to copy or duplicate a slice in golang with examples.


Using the built-in copy() function:

This method takes an original slice of integers as an input and creates a new slice duplicate of the same length. It then uses the built-in copy() function to copy the elements of the original slice into the duplicate slice. The number of elements copied is the minimum length of the two slices.

package main

import (
	"fmt"
)

func main() {
	original := []int{1, 2, 3, 4, 5}

	// Using the built-in `copy()` function
	duplicate := CopySlice(original)
	fmt.Println("Original Slice", original)
	fmt.Println("Duplicate Slice", duplicate)
}

func CopySlice(original []int) []int {
	duplicate := make([]int, len(original))
	copy(duplicate, original)
	return duplicate
}

Output

Original Slice [1 2 3 4 5]
Duplicate Slice [1 2 3 4 5]

Using the append() function:

This method takes an original slice of integers as an input, creates a new slice with nil as its initial value, and then uses the append() function to append all elements of the original slice to the new slice.

By using the append() function and passing an existing slice as the last argument, it is possible to create a new slice with the same elements as the original slice.

package main

import (
	"fmt"
)

func main() {
	original := []int{1, 2, 3, 4, 5}

	// Using the built-in `append()` function
	duplicate := CopySlice(original)
	fmt.Println("Original Slice", original)
	fmt.Println("Duplicate Slice", duplicate)
}

func CopySlice(original []int) []int {
	return append([]int(nil), original...)
}

Output

Original Slice [1 2 3 4 5]
Duplicate Slice [1 2 3 4 5]

Using a for loop:

This method takes an original slice of integers as an input, creates a new slice duplicate of the same length, and then iterates over the elements of the original slice using a for loop. It then assigns the value of each element to the corresponding index of the duplicate slice.

package main

import (
	"fmt"
)

func main() {
	original := []int{1, 2, 3, 4, 5}

	// Using the `for`loop
	duplicate := CopySlice(original)
	fmt.Println("Original Slice", original)
	fmt.Println("Duplicate Slice", duplicate)
}

func CopySlice(original []int) []int {
	duplicate := make([]int, len(original))
	for i, v := range original {
		duplicate[i] = v
	}
	return duplicate
}

Output

Original Slice [1 2 3 4 5]
Duplicate Slice [1 2 3 4 5]

Using the make() function with a composite literal:

This method takes an original slice of integers as an input, creates a new slice duplicate of the same length using the make() function, and then uses the copy() function to copy the elements of the original slice into the duplicate slice.

package main

import (
	"fmt"
)

func main() {
	original := []int{1, 2, 3, 4, 5}

	// Using the `make()` function
	duplicate := CopySlice(original)
	fmt.Println("Original Slice", original)
	fmt.Println("Duplicate Slice", duplicate)
}

func CopySlice(original []int) []int {
	duplicate := make([]int, len(original))
	copy(duplicate, original)
	return duplicate
}

Output

Original Slice [1 2 3 4 5]
Duplicate Slice [1 2 3 4 5]

Using the reflect.Copy() function:

This method takes an original slice of integers as an input, creates a new slice duplicate of the same length using the make() function, and then uses the reflect.Copy() function to copy the elements of the original slice into the duplicate slice. The reflect.Copy() function can copy elements from any data type that implements the SliceHeader interface.

package main

import (
	"fmt"
	"reflect"
)

func main() {
	original := []int{1, 2, 3, 4, 5}

	// Using the `reflect.Copy()` function
	duplicate := CopySlice(original)
	fmt.Println("Original Slice", original)
	fmt.Println("Duplicate Slice", duplicate)
}

func CopySlice(original []int) []int {
	duplicate := make([]int, len(original))
	reflect.Copy(reflect.ValueOf(duplicate), reflect.ValueOf(original))
	return duplicate
}

Output

Original Slice [1 2 3 4 5]
Duplicate Slice [1 2 3 4 5]

Conclusion

In conclusion, creating a copy of a slice in Go is a simple task that can be achieved through a few different methods. The methods discussed in this article include:

  • Using the built-in copy() function.
  • Using the append() function.
  • Using a for loop.
  • Using the make() function with a composite literal.
  • Using the reflect.Copy() function.

All of these methods will create a new slice with a new header pointing to the same underlying array as the original slice, which means that changes made to the elements of the new slice will be reflected in the original slice and vice versa.

© 2023 W3Basic. All rights reserved.

Follow Us: