Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Arrays & Slices  ›  Lesson

Slices: Capacity and Growth

Capacity and Growth 16 minA slice is a small view of an underlying array with a length and a capacity, slicing shares that array, and append writes into it while capacity remains but moves to a new, larger array when it runs out.

Slices: Capacity and Growth

tally collects words into a slice as it reads. Slices look like simple growable lists, and most of the time they behave like one. The exception — two slices quietly sharing memory — produces one of Go's most confusing bugs, and it is completely predictable once you can see a slice's three parts.

The rule

A slice is a window on an array: pointer, length, capacity.

A slice value holds three things:

  • a pointer to an element of an underlying array,
  • a length (len): how many elements the window shows,
  • a capacity (cap): how many elements exist from the start of the window to the end of the array.

Slicing shares. s[low:high] makes a new window on the same array. Its length is high - low, and its capacity runs to the end of the array: cap(s) - low.

words := []string{"the", "cat", "sat", "down"}
first := words[:2]
fmt.Println(len(first), cap(first)) // 2 4

append uses spare capacity first. If len < cap, append writes into the existing array and returns a slice with a larger length. If there is no room, it allocates a new, larger array (often about double for small slices; the exact growth is up to the runtime), copies the elements across and returns a slice pointing there.

That is why you always write s = append(s, x): the result may point somewhere new.

Now the bug:

first = append(first, "ran")
fmt.Println(words) // [the cat ran down]

first had room, so "ran" overwrote "sat" in the array both slices share.

The fix is to leave no spare room: the full slice expression words[:2:2] sets capacity to 2, so the next append must allocate. slices.Clone(words[:2]) makes a separate copy.

The shortcut

Before any append on a slice of a slice, write down (len, cap) and ask "is there room?" Room → it writes into shared memory. No room → it moves out to a new array.

Tracing the appendStep 1 of 4
  1. The array

    words is a 4-element array: the, cat, sat, down.

Drills

Answer fast — trust the rule.

quick drill

s := []int{10, 20, 30, 40, 50}; t := s[1:3]. What are len(t) and cap(t)?

quick drill

a := []int{1, 2, 3}; b := a[:1]; b = append(b, 7). What is a?

quick drill

a := []int{1, 2, 3}; b := a[:1:1]; b = append(b, 7). What is a?

quick drill

Why must you write s = append(s, x) rather than just append(s, x)?

Remember

  • A slice is a window on an array: pointer, length, capacity.
  • Shortcut: write down (len, cap) and ask "is there room?" before appending.
  • Trap: appending to a sub-slice can overwrite the original; s[a:b:b] or slices.Clone prevents it.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainThe word that changed by itself

In tally, words := []string{"the", "cat", "sat", "down"}, then first := words[:2] and first = append(first, "ran"). Explain what words holds afterwards and why, and how to make first safe to append to.