Golang Basics: Array and Slices

Nikhil Vaidyar
6 min readJun 20, 2021

Hey everyone, Today, I will talk about some basic concepts of Go in which we discuss the building block data structure, which is arrays and slices.

We all are accustomed to knowing how arrays work, and we also use this data structure in most of our projects.

Hence, I will rephrase it once again to understand arrays in Golang.

Arrays in Go

Arrays are fixed-size elements and have contiguous memory, and they cannot shrink and grow in size. Some advantages of using arrays are that they have random access, and they are cache-friendly. Here’s a simple representation of the array in Go.

Representation of an array in Go
Representation of an array in Go
var myArr [4]int
myArr[2] = 33
newArr := myArr
// newArr = 33

n Golang, variables are explicitly declared and used by the compiler.
The in-memory representation of [4]int in a sequenced manner:

Pictorial representation of an array
Pictorial representation of an array

An array variable denotes the entire array, which means assigning an array variable will create a copy of its content.

It can also be declared as:

values := [4]string{'John', 'Bob', 'Kyle', 'Jack'}
values := [...]string{'Austin', 'John'}

You must be thinking what those three dots are in an array […]?

Okay, there is a slight difference between []string and […]string, []string is nothing but a string array. The […]string is a parameter syntax that makes it a variadic parameter; it will accept 0 and more string values and reference them as a slice. So regardless of giving the element count in an array, you can just annotate like this […] to make it more dynamic.

The built-in function len usually just returns the length of the array. Talking about loops we use it to iterate over an array of single and multi-dimensional arrays, although there is another controlled way that Go provides us to serve, there is a keyword called range which iterates as the same as for loop but in the hand, it does more elegantly and cleanly. Range with maps works efficiently.

Some limitations of using arrays in Go:

  • Arrays in Go are not resizable and dynamic.
  • Passing an array to a function as a parameter, you passing the copy of an array, which means that any changes you will be doing inside the function will be lost after the function gets executed.
  • Passing a large array to a function can be pretty slow. To overcome this inefficiency, Go has a dynamic array called slices, by which we can overcome all these limitations.

Slices in Go

In simple words, slices are dynamic arrays. They provide more flexibility and efficiency over arrays.

  • Slices are implemented using arrays internally, which means that Go uses an underlying array for each slice.
  • Slices are passed by reference to the functions, which means the memory address of the slice variable is passed. Any changes that you will make to the slice will not be lost after the function execution.
  • Passing a big slice is much faster than passing an extensive array to the function because Go will not have to copy the slice. It will just pass the memory address to the slice variable.

A slice literal is declared exactly like a normal array in Go, only without the element count.

myIntSlices := []int{12, 45, 89, 90}
myStringSlices := []string{'John', 'Diana', 'Jess', 'Rachel'}

Slices can also be created by a built-in function called “make”.

Go (make) function signature
Go (make) function signature
randomSlice := make([]byte, 5, 5)
// randomSlice = []byte{0, 0, 0, 0, 0}

It is optional to pass capacity in the make function. It’s just that by default, the capacity will take the length values.

Internals of Slices

The internals part of slices consists of a pointer to the array, length, and capacity.

Internals of slices
Internals of slices

Length: It is the number of elements referred to by the slice.
Capacity: It is the number of elements in an array.

Slices can also be formed by “re-slicing” an array or slice.

items := []int{1, 2, 3, 4, 5}
items[1:3] // {2, 3}
items[2:] // {3, 4, 5}
items[:3] // {1, 2, 3}
items[:] // {1, 2, 3, 4, 5

Note: Ever wonder what’s this “:” notation means, it means to create a new slice that references an existing slice.

This way it creates a new slice that points to the original slice. If modifying the newly created array with the original array or slice becomes efficient. Hence, it is mutable in nature.

A slice cannot be grown beyond its capacity. Hence it will end in runtime panic or indexing out of the bounds of a slice.

Growing nature of slices

Copy: This function supports copying between slices of different lengths. The in-built copy function copies the minimum len(s2) and len(s1) elements.

Go (copy) function signature
Go (copy) function signature

Copy function copies the data from a source slice to the destination slice and returns the number of elements copied to the destination slice.

Here’s an example:

Go — copy function example
Go — copy function example

Append: In simple terms, you already know it means to add something. But, in Go, the append function means to append the elements for, say, x elements to the end of the slice s, and it grows the slice if the capacity is needed.

Go (append) function signature

Here’s an example for the append function in practice:

Go — append function example
Go — append function example

Functions like append provide total control of the way the slice is grown. Go shows us that to grow a slice, we will need to implement an append function and not refer to an index that does not exist. It could end up giving an error message: panic: runtime error: index out of range.

I think you probably got an idea of how to implement the arrays and slices, when and why?

Thanks for reading this far. If there are any blunders in this post, feel free to suggest possible changes required to make this post more informative. It was just brief information to get familiar with the go concepts. Meanwhile, you can reach out to the official Go blog website for more: https://blog.golang.org/

Links which I referred to:

https://blog.golang.org/slices-intro
If you want to know more about slices, you can check out this blog too: https://blog.golang.org/slices

Books which I referred to:

Mastering Go by Mihalis Tsoukalos
The Go Programming Language by Alan A. A. Donovan & Brian W. Kernighan

--

--

Nikhil Vaidyar

Maintaining consistency | CNCF Contributor | Golang | Docker | Kubernetes