Learning Golang: Easy way to remember a slice's capacity

I’m learning Golang since last week. Figured I’ll learn a language that’s not similar to Ruby and Javascript. Decided to go with go as it seems to have good adoption, which means “GO JOBS ARE AVAILABLE”.

While learning about slices, the notion of capacity was difficult for me to understand.

But then I had an “oh-shit-yup-makes-sense-now” moment about how to think about the capacity.

Capacity of a slice is defined as:

The capacity of a slice is the number of elems in the underlying array,
counting from the 1st elem in the slice.

Given this slice/array (and this helper-function):

s := []int{2, 3, 5, 7, 11, 13}


func printSlice(s []int) {
	fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}

We can create various slices out of this slice s.

But first, the len and cap of the original slice s:

// len: 6, cap: 6
// op: [2 3 5 7 11 13]
printSlice(s)

It has 6 items in slice. So its len is 6 and its cap is 6.

Wait, how’s the cap 6?

Ok, here’s the “oh-shit-yup-makes-sense-now” moment this post is all about.

A slice’s capacity depends only upon the start and index of the slice. Ignore the end index while calculating the capacity.

Here’s the formula version of it:

slice’s capacity = underlying array’s length - slice’s start index

Using this, you can calculate (and visualize) the capacity easily.

Here are various slices created out of the original slice s above.

  // zero-length: can be extended
  s1 := s[:0]
  // len: 0, cap: 6 
  // has no elems, but can be extended to hold (all) 6 items
  // op: []
  printSlice(s1)
  // capacity is 6 because of the formula:
  // capacity = len(s) - start-index-of-slice
  // capacity = 6 - 0 = 6


  // zero-length: CANNOT be extended
  s4 := s[6:]
  // len: 0, cap: 0
  // has no elems, and can't be extended too
  // op: []
  printSlice(s4)
  // capacity = len(s) - start-index-of-slice
  // capacity = 6 - 6 = 0


  // extending
  s2 := s[:4]
  // len: 4, cap: 6
  // has 4 elems (from idx 0 till idx 3),
  // and can be extended to hold a total of (all) 6 items
  // op: [2 3 5 7]
  printSlice(s2)
  // capacity = len(s) - start-index-of-slice
  // capacity = 6 - 0 = 6
  // (notice that the end index 4 has nothing to do with this)


  // shortening
  s3 := s[2:]
  // len: 4, cap: 4 
  // has 4 elems after the 2nd item. Can only hold a total of 4 items.
  // (can't extend to left. only right is allowed)
  // op: [5 7 11 13]
  printSlice(s3)
  // capacity = len(s) - start-index-of-slice
  // capacity = 6 - 2 = 4

The end.

Thoughts on the post are welcome! Mail me at prasanna@npras.in or .