22 Коллекции
Когда append перевыделяет массив?
Ответ
append дописывает элементы в хвост. Если len + сколько_добавили не больше cap, элементы пишутся в тот же массив. Если ёмкости не хватает, рантайм выделяет новый массив, копирует старые элементы и возвращает заголовок уже на него. Старый slice при этом не обновляется сам — результат нужно сохранить: s = append(s, x).
Подробнее
В примере у a ёмкость ровно 2, поэтому третий элемент не влезает. b получает новый массив. Запись b[0] = 9 не меняет a, и сравнение адресов первых элементов даёт false.
Пока ёмкость общая, правка элемента через один slice видна в другом. Поэтому функцию, которая и добавляет элементы, и меняет старые, проектируют так, чтобы вызывающий пользовался только возвращённым slice.
package main
import "fmt"
func main() {
a := make([]int, 2, 2)
a[0], a[1] = 1, 2
b := append(a, 3)
b[0] = 9
fmt.Println("a", a)
fmt.Println("b", b)
fmt.Println("делят массив:", &a[0] == &b[0])
}