Ответ вслух Middle Слайсы и мапы изнутри обновлено

Как работает append в Go

Вопрос

Расскажите, что происходит при s = append(s, x), и почему результат append обязательно присваивают.

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

append смотрит на ёмкость. Если len < cap, он кладёт элемент в следующий свободный слот того же массива и возвращает заголовок с len на единицу больше.

Что должно прозвучать в ответе

  • Если `len < cap`, элемент пишется в существующий массив, len растёт на 1

  • Если места нет, выделяется новый массив большей ёмкости, данные копируются

  • Рост: удвоение для маленьких, плавнее после ~256 элементов, плюс округление под классы аллокатора

  • append возвращает новый заголовок, старый может указывать на другой массив и иметь старый len

  • Подслайсы одного массива могут затирать данные друг друга через append

  • Предвыделение `make([]T, 0, n)` убирает лишние аллокации

Что могут спросить следом

  • Почему точное значение cap после append нельзя закладывать в тесты?
  • Как удалить элемент из середины слайса без утечки указателей?
  • Что сделает append, если слайс nil?

Разбор

append смотрит на ёмкость. Если len < cap, он кладёт элемент в следующий свободный слот того же массива и возвращает заголовок с len на единицу больше. Если места нет, рантайм (growslice) выделяет новый массив: для маленьких слайсов примерно вдвое больше, после порога в 256 элементов рост плавнее, около 1.25x плюс константа, и итог округляется до класса размера аллокатора. Старые элементы копируются, и с этого момента новый слайс живёт отдельно от старого. Поэтому результат всегда присваивают: заголовок может быть другим и по указателю, и по len. Отсюда же баги: два подслайса одного массива при append перезаписывают друг друга, пока есть ёмкость. Лечится полным срезом a[i:j:j] или копированием. Если размер известен, делаю make([]T, 0, n), чтобы не было промежуточных аллокаций и копий. append к nil-слайсу работает как к пустому.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.