A slice is a structure of 3 fields.
- a pointer to the underlying array
- length of the slice
- capacity of the slice
You can see this in slice.go, here https://github.com/golang/go/blob/master/src/runtime/slice.go
Both the slices point to the same memory, any changes to the actual data will impact all the slices pointing to the array. So, if you have an array and many slices pointing to the same array, there can be many places where the array can be changed. So, this is a disaster going to happen.
The programmers should avoid exposing the array and always keep it anonymous.
Golang provides make() to achieve this objective. make() allows us to create a slice when the underlying array is not defined.
slice1 := make(type, len) //case 1
slice2 := make(type, len, cap) // case 2
In the first case, the slice is pointing to an array of length ‘len’.
Here, the following statement is true
cap(slice1) = len(slice1) = len
In the second case, slice2 doesn’t occupy the entire underlying array. The array has a length ‘cap’ and slice has length ‘len’. There is space for reslicing.
Changing the length of the slice is called reslicing. It is done by increasing the end index of the slice, until it occupies the entire array.
Increase the slice length by 1
s = s[0:len(s)+1]
Slice length can be reached upto the capacity. If the length crosses the capacity, it will panic at run time.
The capacity is a limitation in reslicing. So, golang provides an built-in function append() to fix this issue.
The built-in append() does the following
- append() appends zero or more values to a slice and returns the resulting slice.
- allocates a new, sufficiently large slice
- always succeeds, unless the computer runs out of memory
append() may either modify its argument in-place or return a copy of its argument with an additional entry, depending on the size and capacity of its input. append() function creates a new slice, if the length the slice is greater than the length of the array pointed by the slice.
In the first append(), the argument is modified and in the 2nd append(), a new slice is created.
When you use append on a slice, you should avoid accessing the array anywhere else if you don’t want to be surprised.
append() doesn’t fail unless you run out of memory. The garbage collector won’t release memory if the slice is kept around. It can cause the problem if it is huge, but only a few elements are required.