slice is a wonderful abstraction of a simple array . You get all sorts of nice features, but at the core is array . (I explain the following in reverse order for a reason). Therefore, if / when you specify capacity from 3 , an array of length 3 is allocated in the depth of memory in memory, which you can use before append without the need to reallocate memory. This attribute is optional on the make , but note that slice will always have capacity , regardless of whether you select it. If you specify length (which also always exists), slice will be indexable to that length. The rest of capacity is hidden behind the scenes, so it doesn't need to allocate a whole new array when using append .
Here is an example to better explain the mechanics.
s := make([]int, 1, 3)
The base array will be assigned 3 int values of zero (i.e. 0 ):
[0,0,0]
However, length set to 1 , so the slice itself will print only [0] , and if you try to index the second or third value, it will be panic , since the slice mechanics do not. allow it. If you s = append(s, 1) to it, you will find that it was really created to contain zero values up to length , and you will get [0,1] . At this point, you can append again before the entire base array is full, and another append will make it select a new one and copy all the values with double capacity. This is actually a rather expensive operation.
So the short answer to your question is that pre-allocation of capacity can be used to significantly increase the efficiency of your code. Especially if slice will either be very large or contain complex structs (or both), since the zero value for the struct actually the zero value for each of its fields . This is not because it would avoid highlighting these values, as in any case, but because the append would have to redistribute a new array full of these null values each time it would need to resize the underlying array.
A short example of a playground: https://play.golang.org/p/LGAYVlw-jr
source share