liveBook · Manning

Array

As explained in 100 Go Mistakes and How to Avoid Them

A Go array is a fixed-length sequence of elements stored contiguously and serving as the backing storage for slices.

A Go array is a fixed-size sequence of elements. It also supplies the contiguous storage behind a slice. A slice holds a pointer to its backing array, a length, and a capacity. Confusing the array’s allocated space with the slice’s accessible elements leads to indexing mistakes. section 3.4

Allocated does not mean indexable

With `s := make([]int, 3, 6)`, the backing array has room for six elements, but `s` has length three. `s[1] = 1` works; `s[4] = 0` panics with an index-out-of-range error. Use `s = append(s, 2)` to occupy the next available position and increase the slice’s length. section 3.4

Ranging over an array copies it

Consider `a := [3]int{0, 1, 2}` followed by `for i, v := range a { a[2] = 10; if i == 2 { fmt.Println(v) } }`. This prints `2`, not `10`: range evaluated and copied the array before the loop, while the assignment changed the original. To observe the current value, read `a[i]`; to range without copying the whole array, use `range &a`. section 4.2.2

An append can change another slice

Given `s1 := []int{1, 2, 3}`, `s2 := s1[1:2]`, and `s3 := append(s2, 10)`, the results are `s1=[1 2 10]`, `s2=[2]`, and `s3=[2 10]`. The append fits within `s2`’s capacity, so it writes to the array shared with `s1`. Once capacity is exhausted, append instead creates another array and copies the elements. section 3.9 section 3.4

Choose the remedy according to what must remain independent:

  • If a function may append to a prefix but must not overwrite the original slice’s next element, pass a capacity-limited slice such as `s[:2:2]`. Its append must use another backing array; updates to elements already shared are still visible. section 3.9
  • If the function must not change shared elements either, copy the elements into a separate slice before passing it. This adds code but separates the storage. section 3.9

How 100 Go Mistakes and How to Avoid Them covers it

How deep it goes
Traces array copying during range and backing-array sharing during append, then gives targeted alternatives.
Examples
Uses a three-length, six-capacity slice, a modified array during range, and an append that changes another slice.
What it assumes
Assumes familiarity with Go loops and slice operations while explaining backing arrays, length, and capacity.
What you can do after
Diagnose/debug with it when range prints an old value or append unexpectedly changes a related slice.
How it connects
Connects arrays to slices, length, capacity, append, and range.

Also explained in

Compare how 40 books explain array →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 Go Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.