Классический паттерн (см. SliceTricks). Чтобы вставить x на позицию i и сохранить порядок:
a = append(a[:i+1], a[i:]...)
a[i] = x
Паттерн немного сложный для восприятия. На конкретном примере:
// a = [1, 2, 3, 4], вставляем 99 на позицию i=2
a = append(a[:3], a[2:]...) // [1, 2, 3, 3, 4] — элемент 3 дублируется
a[2] = 99 // [1, 2, 99, 3, 4]
Сложность O(n): весь хвост правее i сдвигается.
Часто встречается другой однострочник: append(a[:i], append([]T{x}, a[i:]...)...). Он короче, но хуже. Внутренний append создаёт временный слайс и копирует хвост лишний раз. Вариант выше сдвигает по месту, без лишней аллокации.
С Go 1.21 то же самое пишется проще:
a = slices.Insert(a, i, x)
Рекомендую использовать именно slices.Insert. Умеет вставлять несколько значений за один проход:
a = slices.Insert(a, i, x1, x2, x3)
В данном случае все три значения вставляются одним сдвигом хвоста, а не тремя. Для длинных слайсов разница будет ощутима.
Если есть потребность часто вставлять в середину большого слайса, то скорее всего нужна другая структура данных. Сложность вставки как O(n) будет влиять на производительность негативно.
Предыдущая заметка из серии — удаление элемента из слайса. Другие базовые темы собраны в дорожной карте по Go.
Теги: