Тип map в Go

Тип map в Go представляет собой неупорядоченную коллекцию пар ключ-значение, где каждый ключ уникален в пределах одной карты. В первом параметре указывается тип ключа, во втором - тип значения. Карты удобны для быстрого доступа к данным по ключу, так как время поиска не зависит от размера карты.

Синтаксис

gomap[KeyType]ValueType

Объявление и инициализация

Для создания карты используется встроенная функция make. Рассмотрим пример создания карты с ключами типа string и значениями типа int:

gopackage main

import "fmt"

func main() {
  ages := make(map[string]int)
  ages["Alice"] = 30
  ages["Bob"] = 25

  fmt.Println(ages)
}

Результат выполнения кода:

gomap[Alice:30 Bob:25]

Инициализация с литералом

Карту можно инициализировать сразу с данными, используя литерал:

gopackage main

import "fmt"

func main() {
  scores := map[string]int{
    "Alice": 95,
    "Bob":   87,
    "John":  92,
  }

  fmt.Println(scores)
}

Результат выполнения кода:

gomap[Alice:95 Bob:87 John:92]

Нулевая карта и проверка существования

Нулевая карта (объявленная без инициализации) равна nil. При обращении к несуществующему ключу возвращается нулевое значение типа. Для проверки существования ключа используется второй параметр при обращении:

gopackage main

import "fmt"

func main() {
  var data map[string]int

  val := data["key"]
  fmt.Println(val)

  val2, ok := data["key"]
  fmt.Println(val2, ok)
}

Результат выполнения кода:

go0
0 false

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

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

gopackage main

import "fmt"

func main() {
  users := make(map[string]string)

  users["user1"] = "Alice"
  users["user2"] = "Bob"
  fmt.Println(users)

  delete(users, "user1")
  fmt.Println(users)
}

Результат выполнения кода:

gomap[user1:Alice user2:Bob]
map[user2:Bob]

Итерация по карте

Для перебора всех элементов карты используется цикл for range. При итерации возвращаются ключ и значение:

gopackage main

import "fmt"

func main() {
  ages := map[string]int{
    "Alice": 30,
    "Bob":   25,
  }

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

Результат выполнения кода:

go"Alice is 30 years old"
"Bob is 25 years old"

Количество элементов

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

gopackage main

import "fmt"

func main() {
  data := map[string]int{
    "a": 1,
    "b": 2,
    "c": 3,
  }

  count := len(data)
  fmt.Println(count)
}

Результат выполнения кода:

go3

Сравнение карт

Карты нельзя сравнивать через оператор ==, за исключением сравнения с nil. Для сравнения содержимого двух карт необходимо писать отдельную функцию:

gopackage main

import "fmt"

func equal(x, y map[string]int) bool {
  if len(x) != len(y) {
    return false
  }
  for k, v := range x {
    if yv, ok := y[k]; !ok || yv != v {
      return false
    }
  }
  return true
}

func main() {
  map1 := map[string]int{"a": 1, "b": 2}
  map2 := map[string]int{"a": 1, "b": 2}
  map3 := map[string]int{"a": 1, "b": 3}

  fmt.Println(equal(map1, map2))
  fmt.Println(equal(map1, map3))
}

Результат выполнения кода:

gotrue
false

Смотрите также

  • тип slice,
    который представляет динамический массив
  • функцию make,
    которая создает и инициализирует карты
  • тип array,
    который представляет массив фиксированного размера
  • тип any,
    который представляет пустой интерфейс для хранения любых типов