0 day streak
go / intermediate
Snippet

Understanding Slice Headers and Shared Backing Arrays

In Go, a slice is a header containing a pointer to a backing array, a length, and a capacity. Slicing an existing slice creates a new slice header pointing to the same backing array. Modifying elements of the new slice directly alters the original slice. Appending to a slice within its capacity overwrites elements in the backing array, whereas appending beyond capacity triggers the allocation of a new backing array.

snippet.go
go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main
import "fmt"
func main() {
original := []int{10, 20, 30, 40, 50}
subSlice := original[1:4]
fmt.Printf("len=%d cap=%d %v\n", len(subSlice), cap(subSlice), subSlice)
subSlice[0] = 99
fmt.Println("Original after modification:", original)
subSlice = append(subSlice, 100)
fmt.Println("Original after append:", original)
}
Breakdown
1
original := []int{10, 20, 30, 40, 50}
Initializes a slice with a length of 5 and a capacity of 5.
2
subSlice := original[1:4]
Creates a sub-slice from index 1 to 3 (inclusive of 1, exclusive of 4). Its length is 3, but its capacity is 4 because it extends to the end of the backing array.
3
subSlice[0] = 99
Modifies the first element of subSlice. Since it shares the backing array, the second element of original (index 1) changes to 99.
4
subSlice = append(subSlice, 100)
Appends 100 to subSlice. Because capacity is 4, it uses the existing backing array, overwriting the last element of original (index 4) with 100.