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:
-
Using the
make
functions := make([]int, 5)
-
Using a slice literal
s := []int{1, 2, 3, 4, 5}
s
: name of the sliceint
: 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
}