When Does append() in Go Create a New Slice?
Context:
The Go append() function is used to append one or more elements to a slice, and it is documented to create a new slice when the capacity of the original slice is insufficient. However, an investigation into a recursive algorithm that adds elements to a slice has shown that slices sent over a channel seem to be modified after they are sent.
Confusion:
This observation contradicts the documentation, which indicates that append() should return a new slice. This confusion arises because the append() documentation refers to the slice data type, while the actual implementation works with slice descriptors.
Resolution:
A slice descriptor consists of three components: a length, a capacity, and a pointer to the underlying data. When append() is called, it returns a new slice descriptor with updated length and capacity. However, the pointer to the underlying data remains the same.
Explanation:
Therefore, while append() does return a new slice descriptor, the actual data is still shared between the old and new slices. This is because the underlying data is stored in a separate memory location pointed to by the slice descriptor.
Example:
The following code illustrates this behavior:
<code class="go">package main import "fmt" func main() { s := make([]int, 0, 5) s = append(s, []int{1, 2, 3, 4}...) a := append(s, 5) fmt.Println(a) b := append(s, 6) fmt.Println(b) fmt.Println(a) }</code>
The output shows that the two modified slices, a and b, share the same underlying data as the original slice s, even though they have different length and capacity.
The above is the detailed content of Does Go\'s `append()` Function Always Create a New Slice?. For more information, please follow other related articles on the PHP Chinese website!