8. Tricky Slices
The Core Problem
Let's Start Simple: What is Capacity?
slice := make([]int, 3, 8)
// ^ ^
// | |
// length capacityslice := make([]int, 3, 8)
// ^ ^
// | |
// length capacitya := make([]int, 3) // length=3, capacity=3 (full!)a β [0][0][0] (all 3 spaces full)b := append(a, 4) // a is full, so create NEW arraya β [0][0][0] (original array, unchanged)
b β [0][0][0][4] (NEW array, bigger)c := append(a, 5) // a is still full, create ANOTHER new arraya β [0][0][0] (original, still unchanged)
b β [0][0][0][4] (its own array)
c β [0][0][0][5] (its own array)i := make([]int, 3, 8) // length=3, capacity=8 (5 empty spaces!)i β [0][0][0][_][_][_][_][_]
^^^^^^^ ^^^^^^^^^^^^^^^^
length=3 capacity=8 (5 empty spots)j := append(i, 4) // i has room, so REUSE the same arraySame underlying array:
[0][0][0][4][_][_][_][_]
^^^^^^^ i still sees these 3
^^^^^^^^^^ j now sees these 4 (SAME ARRAY!)g := append(i, 5) // i still has room, REUSE againSame underlying array:
[0][0][0][5][_][_][_][_]
^^^^^^^ i still sees these 3
^^^^^^^^^^ j sees these 4 (but [3] changed!)
^^^^^^^^^^ g sees these 4
i β [0, 0, 0] (sees first 3)
j β [0, 0, 0, 5] (sees first 4, including the 5!)
g β [0, 0, 0, 5] (sees first 4, including the 5!)fmt.Println("addr of j:", &j[0]) // 0x454000
fmt.Println("addr of g:", &g[0]) // 0x454000 β SAME ADDRESS!someSlice = append(otherSlice, element) // β DANGEROUS!mySlice = append(mySlice, element) // β
SAFEnotebook1 := myNotebook // 3 pages used, 7 blank
notebook2 := append(notebook1, "page 4") // writes on page 4
notebook3 := append(notebook1, "page 4") // OVERWRITES page 4!myNotebook := myNotebook // 3 pages used
myNotebook = append(myNotebook, "page 4") // write on page 4
myNotebook = append(myNotebook, "page 5") // write on page 5