In Go, the built-in functions append, len, and cap play a key role when working with slices.
Example:
arr := []int{1,2,3} arr2 := append(arr, 4) // arr2 may be on the same or a new backing array, depending on cap(arr)
Nuances:
What happens if you "slice off" a piece of a slice and add an element via append? Will it affect the original array?
Answer: If cap allows, append will write the element "at the tail" of the original array, and the changes will be visible through all slices that refer to the same array.
Example:
a := []int{1,2,3,4} b := a[:2] // [1 2], len=2, cap=4 b = append(b, 10) // a changes: a -> [1, 2, 10, 4]
Story
In the team, elements were added to a child slice, and unexpectedly the data in the parent array changed — this caused a mismatch in business logic and complex-to-debug bugs in the distribution of tasks among users.
Story
Upon repeated calling of append on a large slice, it was expected that a new array would always be allocated, but in fact, several parts of the system continued to work with the same "backing array", provoking race conditions and data corruption.
Story
A developer allocated a fixed-size slice using make, but made an error and swapped the arguments: make([]int, cap, len). As a result, logic oriented on capacity unexpectedly operated on length, causing a panic when going beyond s[0:len].