Основы Go

Теория: Практики использования карт

Полезные приёмы работы с картами

Рассмотрим наиболее полезные приёмы (паттерны) при работе с картами. В некоторых случаях мы будем использовать библиотеку samber/lo, которая предоставляет готовые функции для работы с коллекциями и картами.

Инкремент значений (счётчики)

Карты отлично подходят для подсчёта чего-либо. Если ключ отсутствует, доступ map[key] возвращает нулевое значение:

words := map[string]int{}
words["go"]++
words["go"]++

fmt.Println(words["go"]) // => 2

Установка значения по умолчанию

С помощью lo.GetOrElse() можно задать значение по умолчанию, если ключ отсутствует:

import "github.com/samber/lo"

defaults := map[string]string{
	"theme": "light",
}

lang := lo.GetOrElse(defaults, "lang", "en")
fmt.Println(lang) // => en

Сбор ключей или значений

Чтобы получить список всех ключей карты, используйте maps.Keys():

import "maps"

keys := maps.Keys(users)
fmt.Println(keys) // => [alice bob]

Чтобы собрать значения:

import (
  "fmt"
  "maps"
)

values := maps.Values(users)
fmt.Println(values) // => [25 30]

Если нужно отсортировать ключи:

import (
  "fmt"
  "slices"
  "maps"
)

keys := maps.Keys(users)
slices.Sort(keys)
fmt.Println(keys) // => [alice bob]

Вложенные карты (инициализация на лету)

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

settings := map[string]map[string]string{}

user := "alice"
if settings[user] == nil {
	settings[user] = make(map[string]string)
}
settings[user]["theme"] = "dark"

При первом обращении к settings["alice"], если такого ключа ещё нет, Go вернёт nil, но не ошибку. Однако если мы попытаемся сразу обратиться к settings["alice"]["theme"], не проверяя, инициализирована ли внутренняя карта, будет паника времени выполнения.

Этот шаблон — инициализация на лету: если для ключа ещё нет вложенной карты, она создаётся сразу перед использованием.

Рекомендуемые программы