Ответ
В Go есть три основных способа объявления и инициализации слайсов. Выбор способа зависит от того, известен ли заранее размер и нужно ли сразу выделить память.
1. Через var
(нулевое значение)
Создает nil-слайс. Это самый "дешевый" способ, так как память под базовый массив не выделяется.
var s []int
// s == nil
// len(s) == 0, cap(s) == 0
- Когда использовать: Когда вы хотите объявить пустой слайс, в который элементы будут добавляться позже, и вам не важно, будет он
nil
или нет. Это идиоматичный способ объявить пустой слайс.
2. Через make
(с выделением памяти)
Функция make
позволяет создать слайс с заданной длиной (len
) и емкостью (cap
).
// Способ А: len=5, cap=5
s1 := make([]int, 5)
// Способ Б: len=0, cap=10
s2 := make([]int, 0, 10)
- Когда использовать: Когда вы заранее знаете примерное количество элементов, которые будут в слайсе. Указание
capacity
позволяет избежать многократных переаллокаций памяти при добавлении элементов черезappend
, что повышает производительность.
3. Через литерал
Создает слайс и сразу инициализирует его значениями. Длина и емкость будут равны количеству элементов.
// Создает слайс с len=3 и cap=3
s := []int{10, 20, 30}
- Когда использовать: Когда у вас есть начальный набор данных для слайса, например, в тестах или для конфигурационных значений.
Ключевые различия и рекомендации
Способ | Результат | Внутреннее представление (указатель) | Примечание |
---|---|---|---|
var s []T | nil -слайс (len=0 , cap=0 ) | nil | Идиоматичный способ для пустого слайса. Безопасен для append и range . |
s := []T{} | Пустой, но не nil слайс (len=0 , cap=0 ) | Указывает на пустой массив | Функционально почти идентичен nil -слайсу, но не равен nil . |
s := make([]T, 0, N) | Пустой, не nil слайс (len=0 , cap=N ) | Указывает на массив размером N | Лучший выбор, если размер известен заранее. |
Важный аспект: append
и переаллокация
Когда вы добавляете элементы в слайс с помощью append
и его capacity
исчерпана, Go выделяет новый, больший массив и копирует в него все старые элементы. Поэтому критически важно всегда присваивать результат append
обратно в переменную слайса:
// Правильно
s = append(s, 1)
// Неправильно - может привести к потере данных, если произошла переаллокация
append(s, 1)