W3Basic Logo

Go Slice

Brief introduction to slices

A slice is like an array, but it can grow or shrink automatically in size to accommodate the number of elements it contains. This is useful when you don't know in advance how many elements you need to store in a collection as in the following examples:

  • the list of prime numbers below a given number,
  • the list of students in a class,
  • etc.

The type of a slice is []T (e.g. []int or []string).


Creating a slice (with and without make)

Similar to maps, there are two ways to create a slice:

  1. Using the make function

    s := make([]int, 5)
  2. Using a slice literal

    s := []int{1, 2, 3, 4, 5}
    • s: name of the slice
    • int: represents the data type of the slice. In this case, it can hold only the integer values
    • {1, 2, 3, 4, 5}: elements of the slice

The 5 in the first example is the initial length of the slice (named capacity in the documentation), but it doesn't mean that the slice won't be able to grow beyond that.

Retrieving and updating values in a slice

To retrieve a value from a slice, the syntax is exactly the same as for arrays:

package main

import "fmt"

func main() {
    s := []int{1, 2, 3, 4, 5}
    fmt.Println(s[0]) // 1
    fmt.Println(s[4]) // 5
}

Output

1
5

And the assignment operator can be used to update a value:

package main

import "fmt"

func main() {
    s := []int{1, 2, 3, 4, 5}
    s[0] = 10
    fmt.Println(s[0]) // 10
}

Output

10

Finding the length of a slice

We can use the built-in len() function to find the number of elements in a slice. For Example:

package main

import "fmt"

func main() {
    s := []int{1, 2, 3, 4, 5}
    fmt.Println("The length of slice is:", len(s))

}

Output

The length of slice is: 5

Iterating over a slice

To iterate over a slice, we can use two kinds of loops:

package main

import "fmt"

func main() {
    s := []int{1, 2, 3, 4, 5}
    for i := 0; i < len(s); i++ {
        fmt.Println(s[i])
    }
}

Using for range to iterate over a slice

We can also use for range to loop through elements of slice in Golang. For example:

package main

import "fmt"

func main() {
    s := []int{1, 2, 3, 4, 5}
    for i, v := range s {
        fmt.Println(i, v)
    }
}

The first one is closer to the syntax of C and Java, whereas the second one is more idiomatic in Go.

Appending values to a slice

To append a value to a slice and to grow the slice if necessary, we can use the append function:

package main

import "fmt"

func main() {
    s := []int{1, 2, 3, 4, 5}
    s = append(s, 6)
    fmt.Println(s) // [1 2 3 4 5 6]
}
[1 2 3 4 5 6]

Each time the slice grows, the capacity of the slice doubles.

Example

Let's implement the first use case mentioned above: the list of prime numbers below a given number.

package main

import "fmt"

func getPrimes(n int) []int {
    primes := []int{}
    for i := 2; i <= n; i++ {
        if isPrime(i) {
            primes = append(primes, i)
        }
    }
    return primes
}

func main() {
    fmt.Println(getPrimes(10))  // [2 3 5 7]
    fmt.Println(getPrimes(100))
}

There are plenty of ways to write the isPrime function, but here is one possible implementation:

func isPrime(n int) bool {
    if n < 2 {
        return false
    }
    for i := 2; i*i <= n; i++ {
        if n%i == 0 {
            return false
        }
    }
    return true
}

© 2023 W3Basic. All rights reserved.

Follow Us: