Go by Example

Slices

Dynamic sequences built on arrays, including length, capacity, append, and shared backing storage.

A slice describes part of an underlying array. Its length is the number of accessible elements; its capacity is the space available from its first element.

Use make to choose an initial length and capacity. append adds elements and returns the resulting slice:

package main
 
import "fmt"
 
func main() {
    values := make([]int, 0, 2)
    values = append(values, 10, 20)
    fmt.Println(len(values), cap(values)) // 2 2
 
    values = append(values, 30)
    fmt.Println(values, len(values), cap(values))
}

A sub-slice shares its backing array with the original. Use copy when you need independent storage:

original := []int{1, 2, 3}
part := original[:2]
part[0] = 9
fmt.Println(original[0]) // 9
 
separate := make([]int, len(part))
copy(separate, part)
separate[0] = 5
fmt.Println(original[0]) // still 9

In production

Use a sub-slice only when sharing its backing array is safe. If the expected size is known, provide a capacity to make to reduce growth allocations. Appending may allocate a new array when capacity runs out, so use the returned slice.

Enjoyed this? Get more software craft delivered to your inbox.