← Все этапы
03 · ДАННЫЕ И ТИПЫУрок 14 из 3325 минут

Срезы: гибкие последовательности

Создаём срезы, выбираем диапазоны, добавляем элементы и понимаем длину и ёмкость.

Срез смотрит на последовательность

Срез похож на последовательность элементов с удобной длиной, которая может меняться. Технически он описывает участок базового массива, поэтому два среза иногда могут видеть одни и те же элементы.

Литерал []string{"чай", "кофе"} создаёт срез сразу с данными. Выражение items[a:b] берёт элементы от индекса a включительно до b не включительно. Если начало опустить, оно будет нулём; если опустить конец, срез дойдёт до конца доступной длины.

len — текущее число элементов, а cap — сколько элементов помещается от начала среза в его базовом массиве. append возвращает новый срез; всегда присваивай результат обратно, поскольку при нехватке ёмкости Go может выделить другой базовый массив.

Пример

package main

import "fmt"

func printQueue(queue []string) {
	for position, name := range queue {
		fmt.Printf("%d. %s\n", position+1, name)
	}
}

func main() {
	queue := make([]string, 0, 4)
	queue = append(queue, "Лена", "Игорь", "Марат")
	printQueue(queue[:2])
	queue = append(queue, "Оля", "Нина")
	fmt.Printf("длина: %d, ёмкость: %d\n", len(queue), cap(queue))
	printQueue(queue)
}

Функция принимает []string, поэтому ей подходит срез любой длины. После добавления двух имён выводятся все пять участников; ёмкость после роста может быть больше запрошенной и зависит от реализации Go, поэтому программу не следует проверять по конкретному числу cap.

Разделение с базовым массивом

Изменение элемента в срезе может изменить и другой срез, если оба ссылаются на один базовый массив. Добавление в конец также может использовать уже имеющуюся ёмкость. Если данным нужна независимость, скопируй их в новый срез с помощью copy или выдели новый массив.

Нельзя нарезать за пределами доступной длины базовой последовательности. Для пустого среза можно заранее зарезервировать место: make([]int, 0, 10) создаёт длину 0 и ёмкость не меньше 10.

Практика

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

Создай срез из трёх названий задач: «почта», «отчёт», «звонок». Напиши функцию, которая принимает []string и печатает элементы с номерами. Выведи весь список, добавь через append задачи «врач» и «покупки» именно в таком порядке, снова выведи весь список из пяти задач, затем выведи только добавленную часть срезом tasks[3:].

Проверка результата

Как понять, что получилось

Первый вывод содержит 3 задачи в исходном порядке, второй — все 5 задач в порядке добавления, последний — ровно «врач» и «покупки». Результат append присвоен переменной tasks; функция принимает срез, а не массив фиксированной длины.

Срезы: гибкие последовательности | Go | WebSchool · Go