We’ve looked at strings, numbers, and boolean values in Go. Now, we can take a look at more complex types in Go. The two main types that we are going to look at are Arrays and Slices in Go. Slices are used more in Go than arrays but slices are an abstraction on top of arrays in Go.

Arrays in Go

In Go, an array is a sequence of elements with a specific length. Both the type of the elements and the length are part of an array’s type information in Go. If we make a default array of ints of length five; the array will contain five zeros. Arrays are mutable in Go but only the elements can be changed. The length of an array in Go is fixed after declaration. We can change these elements using the index for the array.

In the examples above, you can see that we can define arrays, change their values, and can use the short declaration operator. Note that the index of an array starts at 0 and ends at the length minus one. An array of length five doesn’t have an element at index five. We also can’t use a negative index in an array in Go. 

go_array

Slices in Go

Having fixed sized arrays might seem a little limiting but this is why we have slices in Go. A slice in Go does not include the length in its type information. This means that the slice is actually a dynamically sized piece of data. This is part of why slices are used much more in Go programs. A slice literal is the same as an array literal without the length information.

In the example above, we create an array then use two slices to reference to it. When we change one of the values of one of the slices it also changes that value in the array and the other slice. This happens because slices are references to arrays. When you create a slice in Go, you are creating an array in the memory and referencing it. The slice itself does not hold any data, it just describes an underlying array. This is true even when you create and manipulate a slice without first creating an array. 

go_slicesBecause slices are references to arrays, they also have a capacity. The capacity of a slice is the length of the underlying array. Other slices can also reference the same underlying array like in the example above. You can use the len() and the cap() functions to find the length and capacity of a slice. You can also add values to a slice using a function append(). When you append a slice above its capacity, a new array will be created in memory for the slice to reference. We can also use the make keyword to create slices.

In our example above, we use the make keyword to create two slices. We then create an array and point to it with a third slice. After that, we append three more values to this slice. We then change one of the original indexes to prove that it is no longer pointing at the original array. If you want a more technical explanation about slices then look at this google blog article: Go Slices.

Multidimensional Data

We can also make multidimensional arrays and slices in Go. A multidimensional Array or Slice is an Array of Arrays or a Slice of Slices.  You can denote these multidimensional structures using multiple brackets. Here are a few quick examples.

In our first example, we just define a two-dimensional array of zeroes.  In our second example, we build a two-dimensional slice by creating and appending two slices to our original slice.  Multidimensional arrays and slices can be extremely useful in Go. One easy way to create multidimensional arrays or slices is to use nested for loops. 

Conclusion

In this post, we talked about arrays and slices in Go. We talked about how slices are references for arrays and how arrays have a fixed length in Go. We also talked about how Go manages its memory for arrays and slices. In the end, we looked at multidimensional arrays and slices in Go. In our next few posts, we will look at maps, embedded maps and then functions in Go.