Home > Article > Backend Development > Why does appending to a Go slice sometimes modify the original slice?
Golang Append's Slice Allocation Behavior
In Go, when appending to a slice, it's necessary to understand the allocation behavior to ensure efficient handling.
According to the built-in API documentation, the append() function reallocates and copies data into a new array block when the existing slice's capacity is insufficient. This raises questions about the nature of the slice descriptor and the returned slice from append().
In the provided recursive algorithm for generating combinations, the append() function is used to incrementally construct slices. However, it's observed that slices sent over a channel from the AddOption function are modified after being sent. This contradicts the expectation that append() should return a new slice.
To resolve this apparent discrepancy, it's essential to clarify the distinction between the slice data type and its underlying representation. The slice descriptor consists of two integers (length and capacity) and a pointer to the actual data. When append() creates a new slice, it generates a new slice descriptor but maintains the same data pointer as the original slice. Therefore, changes made to either slice descriptor affect both slices.
To illustrate this, consider the following code snippet:
<code class="go">s := make([]int, 0, 5) s = append(s, []int{1, 2, 3, 4}...) a := append(s, 5) fmt.Println(a) // [1 2 3 4 5] b := append(s, 6) fmt.Println(b) // [1 2 3 4 6] fmt.Println(a) // [1 2 3 4 6]</code>
Initially, s has a capacity of 5 and is constructed using make(). append() is used to add the elements of another slice to s. Then, two new slices, a and b, are created using append() on s with different elements. Observing the output, both a and b contain the same data, indicating that they share the same data pointer. This demonstrates the behavior described above.
To ensure efficient slice manipulation, it's crucial to understand this allocation behavior of append(). If the existing slice's capacity is sufficient, append() will directly manipulate the existing data pointer, making it more efficient.
The above is the detailed content of Why does appending to a Go slice sometimes modify the original slice?. For more information, please follow other related articles on the PHP Chinese website!