A common mistake is to treat a slice’s spare capacity as elements that are already available. A Go slice has a length and a capacity: length counts its current elements; capacity describes space in its backing array. Only elements within the length can be indexed. section 3.4
Allocated does not mean indexable
With `s := make([]int, 3, 6)`, `s` prints as `[0 0 0]`. Assigning `s[1] = 1` works, but `s[4] = 0` panics with “index out of range [4] with length 3.” Use `s = append(s, 2)` to put an element into the spare space; the length then becomes 4. section 3.4
Length also determines how much work `copy` can do: it copies at most the smaller of the source and destination lengths. A destination with spare capacity but zero length receives no elements. Give it sufficient length before copying; pass the destination first. section 3.8
src := []int{0, 1, 2}
var dst []int
copy(dst, src)
fmt.Println(dst)
The nil destination has length zero, so this copy prints `[]`. section 3.8
src := []int{0, 1, 2}
dst := make([]int, len(src)) #1
copy(dst, src)
fmt.Println(dst)
Giving the destination the source’s length lets the copy print `[0 1 2]`. section 3.8
When the result size is known, choose length to match how elements will be added. Use `make([]Bar, 0, n)` with `append`, or `make([]Bar, n)` with indexed assignments. Do not append to the latter expecting to fill its existing slots: it already contains `n` zero-valued elements. If the final count is uncertain, a known upper bound can still be useful as capacity. section 3.5
