A Go slice can have room to grow without exposing that room as elements. Its header holds a pointer to the start of its view of a backing array, a length, and a capacity. Length counts accessible elements; capacity counts how many elements the slice can hold from that starting point within its current storage. section 4.2
Capacity matters when creating, growing, or deriving a slice:
- Use make([]T, length, capacity) to reserve storage beyond the initial length. The reserved elements are not yet accessible through the slice, and capacity must be at least length. section 4.2.2
- Assign the result of append back to the slice. If capacity remains, append can extend its length in the existing backing array; otherwise, it allocates a larger array and copies the values. section 4.2.4
- Use a[low:high:max] when a derived slice should have less capacity than it would normally inherit. The max index limits how far that slice can extend into the original storage. section 4.2.6
Watch growth across an append
For intSlice := []int{10, 20, 30}, len(intSlice) and cap(intSlice) are both 3. After intSlice = append(intSlice, 40), its length is 4 and the illustrated capacity is 6: the append required new storage. A subsequent append can use that spare capacity. section 4.2.4
Listing 4.47 Slice expressions with and without a max value
intSlice := []int{1, 2, 3, 4, 5}
newSlice1 := intSlice[:2] // [1 2]
newSlice2 := intSlice[:2:3] // [1 2] (same values, less capacity)
Compare intSlice[:2] with intSlice[:2:3]: both expose the same two values, but the three-index expression gives the new slice less capacity. section 4.2.6




