логотип PurpleSchool
Иконка входа
Вход
  • Обучение
  • Войти
логотип PurpleSchool

Мапы в Go: Полное руководство для начинающих

Картинка поста Мапы в Go: Полное руководство для начинающих

Введение: Что такое мапы в Go?

Мапы - это встроенный тип данных в Go, который представляет собой ассоциативный массив или хеш-таблицу. Они позволяют хранить пары "ключ-значение", где каждому уникальному ключу соответствует определенное значение.

Ключи в мапе должны быть сравнимыми типами, такими как строки, числа или булевы значения. Значения же могут быть любого типа, включая другие мапы или структуры.

Вот простой пример объявления мапы, где ключи - строки, а значения - целые числа:

var ages map[string]int

Здесь ages - это мапа, где ключи имеют тип string (строка), а значения - int (целое число).

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

Далее мы подробно разберем, как создавать, изменять и работать с мапами в Go.

Создание мап

Есть несколько способов создать мапу в Go. Самый простой - использовать встроенную функцию make():

ages := make(map[string]int)

Эта запись создает пустую мапу ages, где ключи - строки, а значения - целые числа.

Другой способ - с помощью литерала мапы:

ages := map[string]int{
    "Alice": 25, 
    "Bob":   30,
    "John":   60,
}

Здесь мы создаем мапу ages и сразу заполняем ее парами ключ-значение. Каждая пара указывается через двоеточие ключ: значение и отделяется запятыми.

Важно понимать, что мапа - это ссылочный тип. Когда вы присваиваете одну мапу другой, они обе указывают на одни и те же базовые данные. Изменения в одной мапе будут видны в другой.

ages1 := map[string]int{ 
    "Alice": 25,
}
ages2  := ages1
ages2["Alice"] = 30
fmt.Println(ages1) // map[Alice:30]

В этом примере изменение значения по ключу "Alice" в ages2 также меняет значение в исходной мапе `ages1, так как обе мапы ссылаются на одни и те же данные.

Работа с мапами

Добавление и изменение элементов

Чтобы добавить новую пару ключ-значение в мапу или изменить значение по существующему ключу, используйте оператор индексирования []:

ages := make(map[string]int)
ages["Alice"] = 25 // Добавление нового элемента
ages["Alice"] = 30 // Изменение значения

В этом коде ["Alice"] - это ключ. Если такого ключа в мапе еще нет, то будет добавлена новая пара ключ-значение. Если ключ уже существует, значение по нему будет перезаписано.

Получение элементов

Чтобы получить значение по ключу, также используйте оператор [], указав нужный ключ:

ages := map[string]int{
    "Alice": 25,
    "Bob":   30, 
}
fmt.Println(ages["Alice"]) // 25

Здесь мы получаем значение по ключу "Alice", которое равно 25.

Важно учитывать, что при обращении к несуществующему ключу вы получите нулевое значение типа значений в мапе. Для int это будет 0.

ages := make(map[string]int)
fmt.Println(ages["Abcde"]) // 0

Чтобы отличить нулевое значение от несуществующего ключа, используйте идиому присваивания из двух значений:

age, ok := ages["Abcde"]
if !ok {
    fmt.Println("ключ не найден") 
} else {
    fmt.Println(age)
}

В этом примере ok - булева переменная, которая будет равна true, если ключ существует в мапе, и false - если нет.

Перебор элементов

Чтобы перебрать все элементы мапы, используйте цикл for с оператором range:

ages := map[string]int{
    "Alice": 25,
    "Bob":   30,
    "John":   60,
}

for name, age := range ages {
    fmt.Printf("%s is %d years old\n", name, age)
}

На каждой итерации цикла переменная name будет содержать очередной ключ, а age - соответствующее ему значение.

Порядок перебора элементов мапы не гарантируется и может меняться от запуска к запуску программы.

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

Удаление элементов

Чтобы удалить пару ключ-значение, воспользуйтесь встроенной функцией delete():

delete(ages, "Alice")

Эта запись удаляет из мапы ages элемент с ключом "Alice". Если такого ключа нет, ничего не произойдет.

Другие операции с мапами

Проверка на пустоту

Чтобы проверить мапу на пустоту, используйте встроенную функцию len():

ages := make(map[string]int)
fmt.Println(len(ages) == 0) // true

Если len() возвращает 0, значит мапа пуста.

Сравнение мап

В Go нельзя напрямую сравнивать мапы через `==`. Единственное сравнение - проверка на nil:

var ages map[string]int
fmt.Println(ages == nil) // true

Если нужно сравнить содержимое двух мап, придется перебрать их элементы и сравнить по отдельности.

Мапы как значения

Значениями в мапе могут быть не только простые типы вроде строк и чисел, но и другие мапы или структуры.

Пример "мапы мап":

groups := make(map[string]map[string]int)
groups["developers"] = map[string]int{
    "Alice": 25,
    "Bob":   30,
}

Здесь groups - это мапа, где ключи - строки (названия групп), а значения - другие мапы (словари участников с их возрастом).

Заключение

Мапы - мощный и гибкий инструмент в Go. Умение работать с ними пригодится в самых разных задачах - от простого подсчета слов до построения сложных ассоциативных структур.

Помните про особенности мап:

  • Ключи должны быть сравнимыми типами
  • Мапы - ссылочный тип, изменения в копии влияют на оригинал
  • При обращении к несуществующему ключу возвращается нулевое значение типа
  • Порядок перебора элементов не гарантирован

Теперь вы знаете, как объявлять, изменять и перебирать мапы в Go. Пробуйте использовать их в своих программах и экспериментируйте с разными типами ключей и значений.

С мапами ваш Go-код станет более эффективным, выразительным и удобным в работе. Успехов в освоении этой замечательной возможности языка Go!

Карта развития разработчика

Получите полную карту развития разработчика по всем направлениям: frontend, backend, devops, mobile

Комментарии

0

Карта развития разработчика

Получите полную карту развития разработчика по всем направлениям: frontend, backend, devops, mobile