Home >Backend Development >Golang >Why Does Re-slicing a Go Slice Not Always Reduce Its Capacity?

Why Does Re-slicing a Go Slice Not Always Reduce Its Capacity?

Barbara Streisand
Barbara StreisandOriginal
2024-12-17 02:21:24761browse

Why Does Re-slicing a Go Slice Not Always Reduce Its Capacity?

Re-Slicing Slices in Golang

In Go, slices provide a flexible way to manage collections of elements. While creating and accessing slices is straightforward, understanding the behavior of re-slicing them can be tricky. Let's explore a code snippet that illustrates this concept:

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)
}

This code creates a slice a with a length of 5 and a capacity of 5, followed by two slices b and c with lengths and capacities of 0 and 2 respectively. Slice d is then created as a re-slice of c with a start index of 2 and an end index of 5.

The confusing part arises when observing the output:

a len=5 cap=5 [0 0 0 0 0]
b len=0 cap=5 []
c len=2 cap=5 [0 0] //why the capacity of c not 2 but 5 instead
d len=3 cap=3 [0 0 0]

Understanding Re-Slicing

When re-slicing a slice, it's important to remember that slices are not copies of their underlying arrays. Instead, they are windows that reference a portion of the array.

  • In the case of slice c, it's created as a slice of the first two elements of slice b. Since b has a capacity of 5, slice c can be extended to include the remaining three elements. This is why its capacity remains at 5.
  • Slice d is then created as a re-slice of c with a start index of 2. This means that d references the elements of b in the range of [2, 5). Since there are only three elements left in this range, the length of d is 3, and its capacity is 3 (since it's a part of a larger slice with a total capacity of 5).

Further Clarification

The following code exemplifies the close relationship between re-sliced slices:

func main() {
    b := make([]int, 0, 5)
    c := b[:2]
    d := c[1:5] // this is 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] 

This demonstrates that modifying the elements of slice d directly affects the elements of slice c, confirming that both slices share the same underlying data.

The above is the detailed content of Why Does Re-slicing a Go Slice Not Always Reduce Its Capacity?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn