For the answer to this and other slice questions:
SliceTricks.
Go Blog: Go Slices: usage and internals
Go Blog: Arrays, slices (and strings): The mechanics of ‘append’
The Go Programming Language Specification
A slice is represented by the Go runtime as a slice descriptor with a pointer to the underlying array, a length, and a capacity.
type slice struct {
array unsafe.Pointer
len int
cap int
}
A slice descriptor is a window into an underlying array. Multiple slice descriptors can independently point to various subslices of the same underlying array.
Carefully track the slice descriptor pointer, length, and capacity values in the append
9, 9, 9
and append
7, 7, 7, 7, 7
examples.
Appending to and copying slices
If the capacity of s
is not large enough to fit the additional values, append
allocates a new, sufficiently large underlying array that fits both the existing slice elements and the additional values. Otherwise, append
re-uses the underlying array.
package main
import "fmt"
func main() {
{
x := []int{1, 2, 3, 4, 5, 6}
printSlice(&x)
y := x[1:2]
printSlice(&y)
z := append(y, 9, 9, 9)
printSlice(&z)
printSlice(&x)
}
fmt.Println()
{
x := []int{1, 2, 3, 4, 5, 6}
printSlice(&x)
y := x[1:2]
printSlice(&y)
z := append(y, 7, 7, 7, 7, 7)
printSlice(&z)
printSlice(&x)
}
}
func printSlice(s *[]int) {
fmt.Println("ptr:", &(*s)[0], "len:", len(*s), "cap:", cap(*s), "arr:", *s)
}
ptr: 0xc00009e000 len: 6 cap: 6 arr: [1 2 3 4 5 6]
ptr: 0xc00009e008 len: 1 cap: 5 arr: [2]
ptr: 0xc00009e008 len: 4 cap: 5 arr: [2 9 9 9]
ptr: 0xc00009e000 len: 6 cap: 6 arr: [1 2 9 9 9 6]
ptr: 0xc00009e030 len: 6 cap: 6 arr: [1 2 3 4 5 6]
ptr: 0xc00009e038 len: 1 cap: 5 arr: [2]
ptr: 0xc0000a8000 len: 6 cap: 10 arr: [2 7 7 7 7 7]
ptr: 0xc00009e030 len: 6 cap: 6 arr: [1 2 3 4 5 6]