Arrays and Slices

With structs, we can simply collect multiple data types and putting them in one. With arrays, we can group multiple data of the same type.

Create an array

// create an array with can store [4] values
// of type float64
// {assign values}
prices := [4]float64{10.99, 5.99, 34.94, 20.45}

We can also create an array with the var keyword and setting the length.

// This array holds only null values, in this case 3x "" because we didn't
// give any value to this array
var productNames [3]string

Index of an array

We can give the array a value in a specific place. The index starts from 0 ⇐ this is always the first item inside an array.

// First value of the array is now "Space", the others still remain "".
productNames[0] = "Space"

Subset of Arrays with slices

Let's say you only need a certain range of your array. For example, only the first two items. In this case, we can use slices.

prices := [4]float64{10.99, 5.99, 34.94, 20.45}
firstTwoPrices := prices[0:2]

// Output:
[10.99 5.99]

Theoretically, we are defining the range of:

0 = 10.99, 1 = 5.99 and 2 = 34.94. But if you slice an array, the last number of the index is not included. That's why we only get the two values 10.99 and 5.99.

We can also use the following method to start at the first index till the end index we define ourselves and again, the last index is excluded. The same works also with the end of the index:

firstTwoPrices := prices[:2]
// Same output as before
firstTwoPrices := prices[2:]
// Output:
[34.94 20.45]

Arrays and slices, what's the difference?

Slices are like a pointer to an array. When we slice the array inside a new variable, it also modifies the value of our original array, which has its copy inside our memory.

prices := [3]float64{0, 1, 2}
fmt.Println(prices)

// Output: 0 1 2

firstTwoPrices := prices[:2]
fmt.Println(firstTwoPrices)

// Output: 0 1

firstTwoPrices[0] = 3
fmt.Println(prices)

// Output: 3 1 2

That means, when we use a slice, it doesn't create a copy again inside our memory.

Array/Slice methods

We can check the length of an array using the len function.

fmt.Println(len(firstTwoPrices))
// Output: 2

With the cap function, we can check the capacity of our array.

prices := [3]float64{0, 1, 2}
fmt.Println(cap(prices))
// Output: 3

Dynamic Lists with Slices

With slices, we can also create dynamic arrays. Let's say you load a data of prices from a database, where the amount of prices always change. Then, creating an array with a fixed size is very annoying.

If we don't give the length to this array, Go will automatically create an array based on this slice behind the scenes, ditch that array and create a new array once the array grows:

// Creating a empty dynamic array
prices := []float64{}
// Creating a populated dynamic array
prices := []float64{3.55, 1.43, ...}

We can't assign values to indexes which are not part of the array.

There is a built-in function in Go called append, where we pass the slices and the value which we want to add to the slice.

// Creating a empty dynamic array
prices := []float64{}

// Add a new value at the end of the index
append(prices, 8.99)

What this does is it returns us a new slice with the updated array, so we have to pass it in a new variable or re-assign it to the existing one:

// new variable
updatedPrices := append(prices, 8.99)

// assigning to existing one
prices = append(prices, 8.99)

We can also pass as many values as we want to the append function.

prices = append(prices, 8.99, 9.99, 10.99, 11.99, ...)

Unpacking List values

If we want to add values from a list of float64 to another list of float64 for example, this wont be possbile with the following syntax:

prices := []float64{5.5, 10.5}
discountPrices := []float64{3.99, 6.99}

prices = append(prices, discountPrices)

This wont work because we can not pass a list of float64 inside a list of float64 which only takes values. Its not trick to understand, in this example we are passing a list inside a list which can only take the values.

So we have to use the three dots ... at the end of our list we want to give inside another list. That means that Go extracts/unpacks the value of this list and appends it into our other list:

prices := []float64{5.5, 10.5}
discountPrices := []float64{3.99, 6.99}

// Add the ... at the end of a list to unpack its values 
prices = append(prices, discountPrices...)
fmt.Println(prices)

// Output:
[5.5 10.5 3.99 6.99]

Loop through Arrays / Slices

To get all entries an array has, you can simply loop through it:

drinks := [3]string{"Cola", "Ice Tea", "Water"}

for i := 0; i < len(drinks); i++ {
    fmt.Println(drinks[i])
}

// Output
Cola
Ice Tea
Water

Last updated