Срезы и карты в Go: мощные структуры данных
В этом уроке мы изучим две фундаментальные структуры данных в Go — срезы (slices) и карты (maps). Эти инструменты являются основой для работы с коллекциями данных и широко используются в реальных проектах.
Почему срезы и карты важны?
Срезы и карты — это ключевые структуры данных в Go, которые:
- Позволяют эффективно работать с коллекциями
- Предоставляют гибкость в управлении данными
- Оптимизированы для производительности
- Используются в большинстве Go-программ
💡 Интересный факт: В Go нет встроенных динамических массивов, но срезы предоставляют всю необходимую функциональность и даже больше.
Срезы (Slices)
1. Что такое срез?
Срез — это динамическая обёртка над массивом, которая предоставляет:
- Гибкий размер
- Эффективное управление памятью
- Удобные операции с данными
// Создание среза разными способами
slice1 := []int{1, 2, 3} // Литерал среза
slice2 := make([]int, 3) // С помощью make
slice3 := make([]int, 3, 5) // С указанием длины и ёмкости
2. Основные операции со срезами
// Добавление элементов
numbers := []int{1, 2, 3}
numbers = append(numbers, 4, 5) // [1, 2, 3, 4, 5]
// Удаление элемента
numbers = append(numbers[:2], numbers[3:]...) // [1, 2, 4, 5]
// Копирование среза
copySlice := make([]int, len(numbers))
copy(copySlice, numbers)
3. Длина и ёмкость
slice := make([]int, 3, 5)
fmt.Println(len(slice)) // 3 (текущая длина)
fmt.Println(cap(slice)) // 5 (максимальная ёмкость)
// При превышении ёмкости Go автоматически увеличивает срез
slice = append(slice, 1, 2, 3)
fmt.Println(cap(slice)) // 10 (удвоенная ёмкость)
Карты (Maps)
1. Что такое карта?
Карта — это коллекция пар "ключ-значение", которая:
- Обеспечивает быстрый доступ к данным
- Поддерживает уникальные ключи
- Позволяет эффективно искать значения
// Создание карты
ages := map[string]int{
"Иван": 25,
"Пётр": 30,
}
// Добавление элемента
ages["Анна"] = 28
// Проверка существования ключа
if age, exists := ages["Иван"]; exists {
fmt.Printf("Возраст: %d\n", age)
}
2. Операции с картами
// Удаление элемента
delete(ages, "Пётр")
// Итерация по карте
for name, age := range ages {
fmt.Printf("%s: %d лет\n", name, age)
}
// Очистка карты
for key := range ages {
delete(ages, key)
}
3. Особенности карт
// Нулевая карта
var emptyMap map[string]int
fmt.Println(emptyMap == nil) // true
// Создание карты с начальной ёмкостью
scores := make(map[string]int, 100)
// Использование struct{} для множеств
unique := make(map[string]struct{})
unique["value"] = struct{}{}
Практические примеры
1. Фильтрация данных
func filterEven(numbers []int) []int {
result := []int{}
for _, num := range numbers {
if num%2 == 0 {
result = append(result, num)
}
}
return result
}
2. Подсчёт частоты слов
func countWords(text string) map[string]int {
words := strings.Fields(text)
frequency := make(map[string]int)
for _, word := range words {
frequency[word]++
}
return frequency
}
3. Кэширование результатов
type Cache struct {
data map[string]interface{}
mu sync.RWMutex
}
func (c *Cache) Get(key string) (interface{}, bool) {
c.mu.RLock()
defer c.mu.RUnlock()
value, exists := c.data[key]
return value, exists
}
Практические задания
Задание 1: Анализатор текста
Создайте программу, которая:
- Принимает текст от пользователя
- Подсчитывает частоту каждого слова
- Выводит топ-5 самых часто встречающихся слов
- Сохраняет результаты в карту
Задание 2: Система управления задачами
Напишите программу, которая:
- Позволяет добавлять задачи
- Отмечать задачи как выполненные
- Удалять задачи
- Показывать список всех задач
- Использует срезы для хранения задач
Задание 3: Калькулятор статистики
Создайте программу, которая:
- Принимает список чисел
- Вычисляет:
- Среднее значение
- Медиану
- Моду
- Стандартное отклонение
- Использует срезы для хранения и обработки данных
Что дальше?
В следующем уроке мы:
- Изучим указатели в Go
- Познакомимся с интерфейсами
- Узнаем о методах и получателях
- Начнём писать более сложные программы
🎯 Цель урока: К концу этого урока вы должны уметь:
- Эффективно работать со срезами и картами
- Применять их в реальных задачах
- Понимать особенности их реализации
- Оптимизировать работу с коллекциями данных