Как append растит слайс Все знают, что append добавляет элемент в… — Библиотека Go-разработчика | Golang — TG.ME

💡 Как append растит слайс

Все знают, что append добавляет элемент в слайс. А вот что происходит, когда место в массиве кончилось, знают не всегда, и как раз тут прячется пара неожиданностей.

🔵 Пока есть запас

У слайса есть len и cap. Пока len меньше cap, append дописывает элемент прямо в тот же массив и возвращает слайс, который смотрит туда же. Никакого копирования, дёшево. Именно поэтому два слайса, делящие один массив, могут внезапно перетирать данные друг друга при append в один из них.

🔵 Когда запас кончился

Как только cap исчерпан, рантайм выделяет новый массив побольше, копирует туда старые элементы и возвращает слайс уже на новую память. С этого момента старый и новый слайс не связаны, и запись в один не видна в другом. Отсюда правило, которое многих спасало от багов. Всегда присваивайте результат обратно.


s = append(s, x)


🔵 На сколько растёт

Точный коэффициент это деталь реализации, которая менялась от версии к версии, поэтому закладываться на конкретное число не стоит. Грубый ориентир такой. Маленькие слайсы растут примерно вдвое, большие прибавляют около четверти за раз, а переход между режимами сглажен в районе нескольких сотен элементов. Смысл в том, чтобы амортизировать стоимость и не копировать массив на каждом добавлении.

Если вы заранее знаете примерный размер, выделяйте вместимость сразу.


s := make([]int, 0, n)
for i := 0; i < n; i++ {
s = append(s, f(i))
}

Так вы избегаете череды перевыделений и копирований, а заодно снимаете нагрузку со сборщика мусора. На горячих циклах это заметно.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoDeep
👍6🥱4❤2❤‍🔥1🌚1
August 23, 2026 3.4K 24