Перейти к основному содержимому

Map в Go

Map хранит данные, связывая ключи со значениями, и каждый элемент — это одна пара ключ:значение.

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

Чтобы узнать, сколько элементов в map, то есть его длину, вызовите len().

Map, который не был инициализирован, имеет значение nil.

Внутри map хранит ссылки на хеш-таблицу.

Go предлагает несколько способов создать map, и следующие разделы рассматривают их.


Создание map с помощью var и :=

Для создания map с начальными значениями подходят и ключевое слово var, и оператор короткого объявления :=.

Примечание: Не ожидайте, что map сохранит порядок, который вы написали в коде. Go располагает хранимые данные по-своему, чтобы поиск значений оставался быстрым.

Пример

Prompt
Создайте два map с помощью литерального синтаксиса: map string-в-string для автомобиля и map string-в-int для городов. Выведите оба map.
Вывод: Программа на Go и захваченный вывод

Синтаксис map с var и :=

main.go
var a = map[KeyType]ValueType{key1:value1, key2:value2,...}
b := map[KeyType]ValueType{key1:value1, key2:value2,...}

Создание map с помощью функции make()

Функция make() — ещё один вариант. Она даёт вам map, который затем можно заполнять по одному ключу.

Пример

Prompt
Создайте два map с помощью функции make(). Добавляйте пары ключ-значение по одной для автомобиля и для городов. Выведите оба map.
Вывод: Программа на Go и захваченный вывод

Синтаксис map с make

main.go
var a = make(map[KeyType]ValueType)
b := make(map[KeyType]ValueType)

Создание пустого map

Пустой map можно получить с помощью функции make() или объявления var без начального значения.

Примечание: Готов к использованию только первый из них, поэтому выбирать следует make(). Вариант с var равен nil, как показывает вывод, а запись в него вызывает panic во время выполнения.

Пример

Prompt
Покажите разницу между созданием пустого map с помощью make() и без него. Выведите, является ли каждый из них nil.
Вывод: Программа на Go и захваченный вывод

Допустимые типы ключей

Ключ может иметь любой тип, поддерживающий оператор равенства (==), потому что Go должен уметь сравнивать ключи. К таким типам относятся:

  • Булевы значения
  • Числа
  • Строки
  • Массивы
  • Указатели
  • Структуры
  • Интерфейсы (если динамический тип можно сравнивать на равенство)

Три типа не могут быть ключами:

  • Slice
  • Map
  • Функции

Причина в том, что == не определён ни для одного из них.


Допустимые типы значений

У значений такого ограничения нет: map может хранить значения любого типа.


Доступ к элементам map

Чтобы прочитать элемент, укажите его ключ в квадратных скобках после имени map.

Пример

Prompt
Создайте map с помощью make(), добавьте ключи brand, model и year, затем получите и выведите значение "brand".
Вывод: Программа на Go и захваченный вывод

Синтаксис доступа к map

main.go
value = map_name[key]

Обновление и добавление элементов map

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

Пример

Prompt
Создайте map, выведите его, затем обновите один элемент и добавьте новый. Выведите map снова.
Вывод: Программа на Go и захваченный вывод

Синтаксис обновления map

main.go
map_name[key] = value

Удаление элемента из map

Вызовите функцию delete(), передав ей map и ключ, чтобы удалить этот элемент.

Пример

Prompt
Создайте map, выведите его, удалите ключ "year" с помощью delete() и выведите map снова.
Вывод: Программа на Go и захваченный вывод

Синтаксис удаления из map

main.go
delete(map_name, key)

Проверка наличия элементов в map

Поиск по ключу может вернуть два значения, откуда и берётся шаблон val, ok. ok сообщает, существует ли ключ, даже когда его значение пустое, как у day в примере.

Когда вас интересует только наличие ключа, поставьте пустой идентификатор (_) на место val.

Пример

Prompt
Проверьте существующие и несуществующие ключи в map с помощью шаблона val, ok. Также используйте пустой идентификатор, чтобы проверить только наличие ключа.
Вывод: Программа на Go и захваченный вывод

Синтаксис проверки map

main.go
val, ok := map_name[key]

Map являются ссылками

Переменная map ссылается на хеш-таблицу, а не содержит сами данные.

Поэтому, когда две переменные указывают на одну хеш-таблицу, изменение, сделанное через одну из них, видно и через другую.

Пример

Prompt
Покажите, что map являются ссылками. Присвойте map a переменной b, измените значение в b и покажите, что a тоже изменился.
Вывод: Программа на Go и захваченный вывод

Перебор map

Цикл range проходит по всем ключам и значениям map. Не полагайтесь на порядок: он может меняться от запуска к запуску.

Пример

Prompt
Переберите map с помощью range и выведите каждую пару ключ-значение.
Вывод: Программа на Go и захваченный вывод

Перебор map в определённом порядке

У map нет собственного порядка. Чтобы обойти его элементы в определённой последовательности, храните эту последовательность в другой структуре данных, например в slice ключей, и перебирайте её.

Пример

Prompt
Покажите, как перебирать map в определённом порядке, используя отдельный slice, который задаёт этот порядок.
Вывод: Программа на Go и захваченный вывод