← Назад к вопросам

Как записать элемент в Map в Go?

1.0 Junior🔥 181 комментариев
#Основы Go

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Запись элемента в Map в Go

В Go для записи элемента в map (ассоциативный массив) используется синтаксис, похожий на присваивание значения элементу массива или среза. Основной способ — указать ключ в квадратных скобках и присвоить ему значение.

Базовый синтаксис

mapName[key] = value

Где:

  • mapName — переменная типа map
  • key — ключ, по которому будет храниться значение
  • value — значение, ассоциированное с ключом

Примеры использования

1. Простая запись в существующий map

package main

import "fmt"

func main() {
    // Создание map с типом string для ключей и int для значений
    scores := make(map[string]int)
    
    // Запись элементов в map
    scores["Alice"] = 95
    scores["Bob"] = 87
    scores["Charlie"] = 92
    
    fmt.Println(scores) // map[Alice:95 Bob:87 Charlie:92]
}

2. Инициализация с элементами и последующая запись

package main

import "fmt"

func main() {
    // Инициализация map с начальными значениями
    capitals := map[string]string{
        "Россия": "Москва",
        "Франция": "Париж",
    }
    
    // Добавление новых элементов
    capitals["Германия"] = "Берлин"
    capitals["Япония"] = "Токио"
    
    // Обновление существующего элемента
    capitals["Франция"] = "Париж (обновлено)"
    
    fmt.Println(capitals)
    // map[Германия:Берлин Россия:Москва Франция:Париж (обновлено) Япония:Токио]
}

3. Проверка существования ключа перед записью

package main

import "fmt"

func main() {
    inventory := map[string]int{
        "яблоки":  10,
        "бананы":  5,
    }
    
    // Проверяем, существует ли ключ перед обновлением
    item := "апельсины"
    if _, exists := inventory[item]; exists {
        fmt.Printf("Товар '%s' уже существует\n", item)
    } else {
        inventory[item] = 8
        fmt.Printf("Добавлен новый товар: %s\n", item)
    }
    
    // Увеличиваем количество существующего товара
    inventory["яблоки"] += 3
    
    fmt.Println(inventory) // map[апельсины:8 бананы:5 яблоки:13]
}

Важные особенности

Инициализация map

Перед записью элементов map должен быть инициализирован. Попытка записи в nil-map вызовет панику:

var wrongMap map[string]int // nil-map
// wrongMap["key"] = 42     // ПАНИКА: assignment to entry in nil map

correctMap := make(map[string]int) // Инициализированный map
correctMap["key"] = 42             // OK

Конкурентный доступ

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

package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup
    sharedMap := make(map[int]int)
    var mu sync.Mutex
    
    for i := 0; i < 100; i++ {
        wg.Add(1)
        go func(idx int) {
            defer wg.Done()
            mu.Lock()
            sharedMap[idx] = idx * 2
            mu.Unlock()
        }(i)
    }
    
    wg.Wait()
    fmt.Printf("Записано %d элементов\n", len(sharedMap))
}

Поведение при перезаписи

Если ключ уже существует в map, новая запись просто перезапишет старое значение:

counters := make(map[string]int)
counters["requests"] = 1
counters["requests"] = 2 // Перезапись
fmt.Println(counters["requests"]) // 2

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

Для удаления элементов используется встроенная функция delete():

m := map[string]int{"a": 1, "b": 2, "c": 3}
delete(m, "b")
fmt.Println(m) // map[a:1 c:3]

Сложные типы в качестве значений

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

type Person struct {
    Name string
    Age  int
}

func main() {
    people := make(map[int]Person)
    
    people[1] = Person{Name: "Анна", Age: 30}
    people[2] = Person{Name: "Иван", Age: 25}
    
    // Обновление поля структуры
    p := people[1]
    p.Age = 31
    people[1] = p // Важно: перезаписать всю структуру
    
    fmt.Println(people[1]) // {Анна 31}
}

Производительность и внутреннее устройство

Запись в map в Go — операция со средней сложностью O(1), но в худшем случае может деградировать до O(n). Под капотом map реализован как хеш-таблица с разрешением коллизий методом цепочек. При достижении определенного уровня заполнения происходит рехеширование — увеличение размера таблицы и перераспределение всех элементов.

Для оптимизации производительности при известном количестве элементов можно указать начальную емкость:

// Создание map с начальной емкостью 100 элементов
optimizedMap := make(map[string]int, 100)

Заключение

Запись элемента в map в Go выполняется простым синтаксисом map[key] = value, но требует понимания нескольких важных аспектов: необходимости инициализации map перед использованием, отсутствия встроенной безопасности для конкурентного доступа, и поведения при перезаписи существующих ключей. Правильное использование map — важный навык для эффективной работы с Go, особенно учитывая их широкое применение для организации данных по ключам и быстрого доступа к ним.

Как записать элемент в Map в Go? | PrepBro