#9 golang Хэш таблицы - Map (отображение, мапа), "ассоциативные массивы"
Primary tabs
Forums:
Здесь поговорим о хеш-таблице - она же ассоциативный массив, она же — «отображение».
Эта штука позволяет по ключу быстро получить значение. Это удобно, если у вас значений довольно много. Если бы они лежали в слайсе или в обычном массиве, вам бы пришлось все перебирать, а с помощью мэпы мы можем очень быстро (в сравнении с другими структурами) получить нужный элемент, обратившись к нему "по ключу"
Определение мэпы
// инициализация при создании
user := map[string]string{}-- хэш таблица определяется при помощи ключевого слова map, а в квадратных скобках идут тип ключа и затем тип данных, которые и будут размещаться "по своим ключам".
При этом по ключу в мэпе может лежать другая мэпа и т.д. (многомерность).
Что может быть ключом
Любая сравниваемая структура данных может выступать ключом мэпы (чтобы можно было понять к этому ключу вы обращаетесь или нет)
Задание значений хэш таблицы
При объявлении можно и сразу задать конкретные значения:
// инициализация при создании
userData := map[string]string{
"name": "Vasily",
"lastName": "Romanov",
}
fmt.Println(userData)
При этом мапу можно точно так же создать, выделив сразу место под нужное количество элементов, чтобы не приходилось расширять ее во в время выполнения программы:
// сразу с нужной емкостью profile := make(map[string]string, 10)
-- при этом мы не можем применить cap() для получения вместимости, ибо в данном случае второй параметр для определяет её так же четко как для слайсов.
Через len можно получить количество элементов в мапе:
userData := map[string]string{
"name": "Vasily",
"lastName": "Romanov",
}
fmt.Println(len(userData)) // 2
Обращение к элементам
Обратиться к уже лежащим в мапе элементам можно при помощи квадратных скобок:
userData := map[string]string{
"name": "Vasily",
"lastName": "Romanov",
}
// если ключа нет — вернет значение по умолчанию для типа
mName := userData["middleName"]
fmt.Println("mName:", mName)
-- ВАЖНО: Если этого ключа нет в мапе, то вернется значение по умолчанию для типа значения. Про это обязательно надо помнить!
Например, если у вас мапа, в которой значения имеют тип bool, то значение по умолчанию для bool — это false. Если вернется false, то нужно как-то отличать, что вернулось — значение false, которое действительно лежит по ключу, или отсутствие ключа.
Проверка сущестования элемента по ключу
Для разрешения этой ситуации можно получить признак существования ключа, например, с использованием второй переменной при обращении к мапе:
userData := map[string]string{
"name": "Vasily",
"lastName": "Romanov",
}
// проверка существования ключа
mName, mNameExist := userData["middleName"]
fmt.Println("mName:", mName, "mNameExist:", mNameExist)
Так получаем признак существования ключа в переменную mNameExist. В ней будет лежать булевая переменная, которая говорит, был там ключ или нет.
Если же нужно только проверить, есть значение или нет, то можно пропустить первую переменную, используя символ подчеркивания — пустую переменную:
// пустая переменная — только проверяем, что ключ есть
_, mNameExist := userData["middleName"]
fmt.Println("mNameExist:", mNameExist)
Удаление элементов
Значения можно удалять, передав их ключ во встроенную функцию delete():
userData := map[string]string{
"name": "Vasily",
"lastName": "Romanov",
}
// удаление ключа
delete(userData, "lastName")
fmt.Printf("%#v\n", userData)
Что еще почитать
- Go Maps Explained: How Key-Value Pairs Are Actually Stored: https://victoriametrics.com/blog/go-map/
- Log in to post comments
- 48 reads