Sitemap

Slices in Golang: Common Mistakes and Best Practices

4 min readSep 19, 2023
Slices in Golang: Common Mistakes and Best Practices

In this story we want to discuss about slices in Golang and see some different scenarios to avoid common mistakes. Let’s dive in!

A slice in Golang is a dynamically size data structure that is a reference to an underlying array. We must consider passing a slice to a function that modifies it will affect the original slice outside the function.

Since we already know the fundamental of slices in Golang, we will skip the part of introducing len, cap and other basic concepts about slices.

1. nil slices VS empty slices

Although nil slices and empty slices have the same behavior, it is important to know a nil slice has no underlying array while an empty slice referencing an underlying array with zero length.

nil slices vs empty slices

Be aware appending to a nil or zero-length slice needs allocation even though appending to a non-nil slice with enough capacity doesn’t need allocation. So, in most situations having a non-zero capacity (with well predicted value) is advantageous.

2. make another slice form original one

Let’s imagine, we want to pop an item from an original slice to a new one, as below example: (we want to modify s2 that only contains 22,44,88)

make another slice form original one

As we saw in the above code this result could be dangerous to our program so the correct way of doing this kind of operation could be:

make another slice form original one

3. copy slices

If we define a new slice and set it equal to an existing slice, the new defined slice is of a reference type.

copy an slice

The correct way to make a separate copy of an existing slice is by using copy() function, as below:

copy slices in golang

Another quick note is referencing new slice to an existing array, like below:

referencing new slice to an array

This will create a slice referencing myArray. Modifying mySlice will also modify myArray.

4. slices equality

Since Golang 1.21, we can use a slices.Equal() generic function from the standard library like below:

But In previous versions of Golang we could use reflect.DeepEqual().

5. slices and goroutines

slices in Golang are not thread safe. Passing slices without managing the potential race conditions will make our program to behave unpredictable.

We must use mutexes to protect concurrency.

6. using append inside for loops

Using append function inside a for loop can lead our program to a reallocation iteration and it will consume too much resource so we should avoid it as long as we can.

Preallocating with make() function is a viable option when we are working with large datasets.

That’s it. Here is the summary of what we have reviewed so far about slices in Golang.

Summary

  • copy() function makes a copy not a reference
  • Golang 1.21 represents slices.Equal()
  • We should be careful about for loops and append()
  • Watch goroutines and race conditions
  • Use make() for preallocating slices

If you like this article please Clap 👏 and follow me to get more of these Golang contents.

ALSO READ:

--

--

No responses yet