A Comprehensive Guide to Slices in Golang
Slices in Golang

In this article, we will go over the concept of a “slice” which is an important data structure used in Golang. A slice is a data structure that provides a way for you to work with — and manage collections of — data. Slices are built around the concept of dynamic arrays that can grow and shrink as you see fit.
- Slices are dynamic in terms of growth because they have their own built-in function called append which can grow a slice quickly and efficiently.
- You can also reduce the size of a slice by slicing out a part of the underlying memory.
- Slices give you all the benefits of indexing, iteration, and garbage collection optimizations because the underlying memory is allocated in contiguous blocks.
Slice representation
- A slice doesn’t store any data; it just describes a section of an underlying array.
- The slice is represented using a three filed structure name pointer to the underlying array, length, and capacity.
- This data structure works like a descriptor of the slice.

- Pointer: The pointer is used to point to the first element of the array that is accessible through the slice. Here, it is not necessary that the pointed element is the first element of the array.
- Length: The length is the total number of elements present in the array.
- Capacity: The capacity represents the maximum size up to which it can expand.
Declare a slice using the length
When you just specify the length, the capacity of the slice is the same.

Declare a slice with length and capacity
When you specify the length and capacity separately, you can create a slice with the capacity available in the underlying array that you didn’t have access to initially.

Please note, however, that trying to create a slice with a capacity that’s smaller than the length is not allowed.
Create a slice with a slice literal
An idiomatic way of creating a slice is to use a slice literal. It’s similar to creating an array, except you don’t specify a value inside of the [ ] operator. The initial length and capacity will be based on the number of elements you initialize.
Declare a slice with index positions
When using a slice literal, you can set the initial length and capacity. All you need to do is initialize the index that represents the length and capacity you need. The following syntax will create a slice with a length and capacity of 100 elements.

Differences between the declaration of arrays and slices
- If you specify a value inside the [ ] operator, you’re creating an array.
- If you don’t specify a value, you’re creating a slice.
Declare a nil slice
- The zero value of a slice is
nil
. - A nil slice has a length and capacity of 0 and has no underlying array.

Declare an empty slice
You can also create an empty slice by declaring a slice with initialization.

Assign a value to any specific index
To change the value of an individual element, use the [ ] operator.

Take a slice of a slice
Slices are called such because you can slice a portion of the underlying array to create a new slice.

After the slicing operation is performed, we have two slices that are sharing the same underlying array. However, each slice views the underlying array in a different way. The original slice views the underlying array as having a capacity of five elements, but the view of newSlice is different. For newSlice, the underlying array has a capacity of four elements. newSlice can’t access the elements of the underlying array that are prior to its pointer. As far as newSlice is concerned, those elements don’t even exist. Calculating the length and capacity for any newSlice is performed using the following formula.
How is the length and capacity calculated?
For slice[i:j] with an underlying array of capacity k
Length : j - i
Capacity : k - i
Calculating the new length and capacity
For slice[1:3] with an underlying array of capacity 5
Length : 3 - 1 = 2
Capacity : 5 - 1 = 4
The consequences of making changes to a slice
Changes made to the shared section of the underlying array by one slice can be seen by the other slice.
After the number 35 is assigned to the second element of newSlice, that change can also be seen by the original slice in the element.
Run time error showing index out of range
A slice can only access indexes up to its length. Trying to access an element outside of its length will cause a run-time exception. The elements associated with a slice’s capacity are only available for growth.
Growing slices
One of the advantages of using a slice over using an array is that you can grow the capacity of your slice as needed. Golang takes care of all the operational details when you use the built-in function “append”.
- To use append, you need a source slice and a value that is to be appended.
- When your append call returns, it provides you a new slice with the changes.
- The append function will always increase the length of the new slice.
- The capacity, on the other hand, may or may not be affected, depending on the available capacity of the source slice.
Use append to add an element to a slice
When there’s no available capacity in the underlying array for a slice, the append function will create a new underlying array, copy the existing values that are being referenced, and assign the new value.
Use append to increase the length and capacity of a slice

After this append operation, newSlice is given its own underlying array, and the capacity of the array is doubled from its original size. The append operation is clever when growing the capacity of the underlying array. For example, the capacity is always doubled when the existing capacity of the slice is under 1,000 elements. Once the number of elements goes over 1,000, the capacity is grown by a factor of 1.25, or 25%. This growth algorithm may change in the language over time.
Changing to a new slice will not have any impact on the old slice since the new slice now has a different underlying array and its pointer is pointing to a newly allocated array.
Append to a slice from another slice
The built-in function append is also a variadic function. This means you can pass multiple values to be appended in a single slice call. If you use the … operator, you can append all the elements of one slice into another.
Perform index orations on slices
- A slice is formed by specifying a low bound and a high bound:
a[low:high]
. This selects a half-open range which includes the first element but excludes the last. - You may omit the high or low bounds to use their defaults instead. The default is zero for the low bound and the length of the slice for the high bound.
Iterate over slices
Go has a special keyword called range that you use in conjunction with the keyword to iterate over slices.
- The keyword range, when iterating over a slice, will return two values.
- The first value is the index position and the second value is a copy of the value in that index position.
- It’s important to know that range is making a copy of the value, not returning a reference.
The range provides a copy of each element
If you don’t need the index value, you can use the underscore character to discard the value.
The keyword range will always start iterating over a slice from the beginning. If you need more control iterating over a slice, you can always use a traditional for loop.
Conclusions
Over the course of this article, we dove into the concept of slices and discovered a lot about them. We learned that a slice doesn’t store any data — rather it describes a section of an underlying array. We also saw that a slice can grow and shrink within the bounds of the underlying array and used with the index as an array; that the default zero value of a slice is nil; the functions len, cap and append all regard nil as an empty slice with 0 capacity; and that you create a slice either by a slice literal or a call to the make function (which takes the length and an optional capacity as arguments). I hope you have found this helpful!
Disclaimer
I have referenced various blogs, books, and medium stories to materialize this article. For any queries please contact me in the comments.
That’s all for now …. Happy Coding …. Happy Learning 😃