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
index of the slice. Ignore theend
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.