Changing Slice Capacity: Differences Between Dropping First and Last Items
While exploring Go's slice functionality, a common question arises: why does a slice's capacity behave differently when dropping the first n items as opposed to the last n items?
To answer this, it's important to understand that Go slices are structured as follows:
type slice struct { array unsafe.Pointer len int cap int }
Dropping Last n Items
When removing the last n items from a slice (e.g., s = s[:len(s)-2]), the slice's data is still stored in the underlying array. The len field is updated to reflect the new length of the slice, while the cap field remains unchanged. This preserves the same array allocation for the slice.
Dropping First n Items
However, when the first n items are dropped (e.g., s = s[2:]), the slice's underlying data needs to be moved to a different part of the same array. This is because the original memory location for the first n elements is no longer valid. As a result, a new slice is created with a different array pointer, adjusting both the len and cap fields.
To illustrate this, let's enhance the printSlice function to display the pointer to the underlying array:
<code class="go">func printSlice(s []int) { var ptr *int if cap(s) >= 1 { ptr = &s[:cap(s)][0] } fmt.Printf("ptr=%p len=%d cap=%d %v\n", ptr, len(s), cap(s), s) }</code>
Running this modified code demonstrates how the slicing operations alter the pointer, length, and capacity, confirming the behavior described above.
The above is the detailed content of Why Does Dropping First Slice Elements Change Capacity, But Dropping Last Elements Doesn\'t?. For more information, please follow other related articles on the PHP Chinese website!