Learnmonkey Learnmonkey Logo

Go Slices

What are Slices?

Slices are arrays that can grow or shrink in size. However, slice elements must have the same data type, like arrays.

Declaring a Slice

First of all, we can declare a completely empty slice like this:


empty_slice := []datatype
    

If we want to initialize some values, we can do it like this:


non_empty_slice := []datatype{values}
    

The values are seperated by commas. For example:


cities := []string{"New York", "San Francisco", "Los Angeles", "Chicago"}
nums := []int{6,3,6,8,26,34,432}
    

Making a Slice From an Array

To make a slice from an array, we have to specify the start and end indices for the slice:


var example_array = [length]datatype{values} // make an array
example_slice := example_array[start:end] // make a slice from that array
    

For example:


arr1 := [5]string{"Chimpanzee", "Capuchin", "Gorilla", "Macaque", "Orangutan", "Bonobo"}
var slice1 = arr1[1:4]
fmt.Println(slice1)
    

The above code returns:

[Capuchin Gorilla Macaque Orangutan]

Accessing a Slice Element

To access and set slice elements, we use slice indices. Slice indices start at zero for the first element and the index goes up by one for every element we go. For example, the element with slice index 2 is the third element and the element with slice index 4 is the fifth element.

To access slice elements, we type:

slice[index]

We replace slice with the name of the slice variable and index with the index of the element. For example:


websites := []string{"GitHub", "Wikipedia", "Learnmonkey", "Twitter", "Gmail", "Stack Overflow"}
fmt.Println(websites[2])
fmt.Println(websites[5])
fmt.Println(websites[0])
fmt.Println(websites[1])
    

Appending an Element to a Slice

The append function is used to append elements to a slice:


slice_name = append(slice_name, element1, element2, ...)
    
Remember that the append function returns another array. It does not actually append the element to the slice unless we set the slice to the output of it.

Getting the Length of a Slice

To get the length of a slice, we can use two functions: len and cap. The len function returns how many elements are actually in the slice. For example:


countries := []string{"France", "Germany", "Italy", "United States", "Canada", "China", "Mexico"}
fmt.Println(len(countries))
    

The above code returns:

7

However, see what happens if we use the cap function:


fmt.Println(cap(countries))
    

The code returns:

7

Hmm. Same thing. But see what happens when we append an element:


countries = append(countries, "Brazil")
fmt.Println(len(countries))
fmt.Println(cap(countries))
    

Now, we get:


8
14

The reason this is happening is because len returns the number of elements in the slice, but cap returns the equivalent amount of memory the actual slice is using. Whenever we append an element to our slice, Go is making an array behind the scenes with twice the amount of memory as before.

Appending a Slice to a Slice

Appending a slice to a slice also uses the append function:


slice3 = append(slice1, slice2...) // you can add as many slices as you want
    

In the above example, we are appending the slice1 and slice2 slices to the slice3 slice.

The ... is required! If you don't add it, Go will think that you are adding the slices as elements.

Nested Slices

We can put slices inside of slices, just as we could with any other data type. The only difference is that the code is uglier:


mySlice := [][]int{
    {0, 1, 2, 3},
    {4, 5, 6, 7},
}
    

Nested slices can represent tables and matrices.