Слайсы: массив, длина, ёмкость и почему append иногда портит чужие данные
Слайс — не массив, а структура из трёх полей: указатель на массив, длина и ёмкость. Массив под ним может быть общим для нескольких слайсов, и отсюда все сюрпризы. append дописывает в конец: если ёмкости хватает, он пишет в тот же массив, и другой слайс, смотрящий на ту же память, увидит изменение; если не хватает — выделяется новый массив, данные копируются, и связь со старым теряется. Поэтому один и тот же код ведёт себя по-разному в зависимости от ёмкости. Второй источник ошибок — срезание: s[1:3] сохраняет ёмкость до конца исходного массива, поэтому последующий append затрёт соседние элементы; лечится третьим индексом s[1:3:3], ограничивающим ёмкость. Третий — удержание памяти: срез из огромного слайса не даёт сборщику освободить весь массив, и нужен явный slices.Clone.