Sikau

Go · Day 2 · about 40 min

Slices and maps

Length, capacity, shared arrays and the append traps.

The bug that wasn't there yesterday

A teammate writes a helper that returns a list with one extra item. It works in every test. Then, in production, two calls in a row return the same last item — the first result changed after it was returned. Nobody touched it. The culprit is the most famous trap in Go: two slices sharing one backing array.

Slices and maps are the workhorses of Go — almost every program uses them. Five of the mistakes in *100 Go Mistakes* (#20 to #25) are about slices alone. Today you'll see exactly how a slice works underneath, so the trap becomes obvious instead of mysterious.

A slice is a window on an array

An array has a fixed length that's part of its type: [3]int and [4]int are different types, and assigning an array copies all of it. A slice is a small descriptor — a pointer into a backing array, a length and a capacity. len(s) is how many elements you can see; cap(s) is how many fit before the backing array runs out.

package main

import "fmt"

func main() {
	prices := []int{120, 150, 90, 200}
	cheap := prices[1:3]
	fmt.Println(cheap, len(cheap), cap(cheap))
	cheap[0] = 999
	fmt.Println(prices)
}

append(s, x) writes into spare capacity if there is some, and only allocates a new, bigger array when the old one is full. That's why you must always use the result: s = append(s, x). When it grows, Go roughly doubles small slices (and grows big ones by about 25%), rounded up to the memory allocator's size classes — append four ints one at a time to an empty slice and the capacity goes 1, 2, 4, 4.

If you know the final size, allocate once: make([]int, 0, n) gives length 0 and capacity n, so the next n appends never reallocate (mistake #21).

The rest of this lesson

  • When append bitesexplain
  • Mapsexplain
  • Shared arrayspredict
  • Count words, most common firstorder
  • Safe copyfill
  • Words and copieswrite code
  • Badge quizquiz
  • What you learnedrecap

Continue this lesson free — run real code in your browser

Continue with Google

See all 10 lessons of Go