Как создается слайс

Ответ

Слайс в Go создаётся с помощью функции make или литерала. Слайс — это динамически изменяемая структура, которая является ссылкой на базовый массив. Он имеет три ключевых характеристики: указатель на базовый массив, длину (len) и ёмкость (cap).

Примеры создания слайса:

// 1. Через make: make([]тип, длина, ёмкость (опционально))
// Создает слайс типа int с длиной 3 и ёмкостью 5. Элементы инициализируются нулевыми значениями.
s1 := make([]int, 3, 5) // len=3, cap=5, [0 0 0]

// Если ёмкость не указана, она равна длине.
s2 := make([]string, 2) // len=2, cap=2, ["" ""]

// 2. Через слайс-литерал
// Создает слайс с указанными элементами. Длина и ёмкость равны количеству элементов.
s3 := []int{1, 2, 3} // len=3, cap=3, [1 2 3]

// 3. Из существующего массива или другого слайса (слайсирование)
arr := [5]int{10, 20, 30, 40, 50}
// Создает слайс, ссылающийся на весь массив arr
s4 := arr[:] // len=5, cap=5, [10 20 30 40 50]

// Создает слайс из части массива (с 1-го элемента до 3-го (не включая))
s5 := arr[1:3] // len=2, cap=4 (от 1-го элемента до конца массива), [20 30]

// 4. Объявление пустого слайса
// Это nil-слайс. Он не занимает памяти и равен nil.
var s6 []int // len=0, cap=0, nil

// Это пустой слайс. Он не nil, но не содержит элементов.
s7 := []int{} // len=0, cap=0, не nil

Важные моменты:

  • Длина (len): Количество элементов, которые в данный момент находятся в слайсе.
  • Ёмкость (cap): Максимальное количество элементов, которое может содержать слайс, прежде чем потребуется переаллокация базового массива.
  • Расширение (append): При добавлении элементов с помощью append, если текущая ёмкость недостаточна, Go автоматически создает новый, больший базовый массив, копирует в него старые элементы и добавляет новые. Это может быть дорогостоящей операцией.
  • Nil-слайс vs. Пустой слайс: var s []int создает nil-слайс, который равен nil. s := []int{} создает пустой, но не nil-слайс. Оба имеют длину и ёмкость 0. Для большинства операций (например, append, range) они ведут себя одинаково, но их равенство nil отличается. Для проверки на пустоту обычно используют len(s) == 0.