Re-Slicing Slices in Golang
Understanding the behavior of slices can be confusing, especially when re-slicing is involved. In this snippet:
package main import "fmt" func main() { a := make([]int, 5) printSlice("a", a) b := make([]int, 0, 5) printSlice("b", b) c := b[:2] printSlice("c", c) d := c[2:5] printSlice("d", d) } func printSlice(s string, x []int) { fmt.Printf("%s len=%d cap=%d %v\n", s, len(x), cap(x), x) }
The output reveals an unexpected result:
a len=5 cap=5 [0 0 0 0 0] b len=0 cap=5 [] c len=2 cap=5 [0 0] d len=3 cap=3 [0 0 0]
Why does c have a capacity of 5 and not 2? To answer this, we need to understand the concept of slices in Golang.
Slices are lightweight references to arrays. When we create a slice, we provide a range operation (e.g., [:2]) to specify the start and end indices of the referenced array. However, this range operation does not create a copy of the underlying array. Instead, it creates a new slice that shares the same underlying data.
In the given example, b is an empty slice with a capacity of 5. When we create c as a slice of b with a range of [:2], we are essentially creating a reference to the first two elements of b. Since b has a capacity of 5, c can potentially be expanded to include up to 5 elements, even though only 2 elements are currently referenced. This is why c has a capacity of 5 despite its length being 2.
Furthermore, when we create d as a slice of c with a range of [2:5], we are effectively creating a slice that shares the same underlying data as b, but starting from index 2 and extending up to index 5. Since b has a capacity of 5, d has a capacity of 3 (5-2).
The following program illustrates this behavior more clearly:
func main() { b := make([]int, 0, 5) c := b[:2] d := c[1:5] // equivalent to d := b[1:5] d[0] = 1 printSlice("c", c) printSlice("d", d) }
Output:
c len=2 cap=5 [0 1] // modifying d has modified c d len=4 cap=4 [1 0 0 0]
As you can see, modifying d has also modified c, demonstrating that c and d are both windows over the same underlying array, b.
The above is the detailed content of Why Does Re-Slicing a Go Slice Result in Unexpected Capacity Values?. For more information, please follow other related articles on the PHP Chinese website!