Maps

A map maps keys to values:

  • A map is a data structure that provides you with an unordered collection of key/value pairs.

  • В Go map[K]V представляет собой ссылку на хеш-таблицу с ключами K и значениями V. Passing map to function means passing reference to it.

  • The keys must have comparable type.

  • Maps automatically grow as you add key-value pairs to them. If you know how many key-value pairs you plan to insert into a map, you can use make to create a map with a specific initial size.

  • The zero value of a map is nil. A nil map has no keys, nor can keys be added, but could be read. Expression val, ok := m[key] is valid on nil map.

  • Map literals are like struct literals, but the keys are required.

  • Slices, maps, and functions cannot be compared using ==, and may not be used as map keys. You can compare maps against nil.

  • Maps are not safe for concurrent use: it's not defined what happens when you read and write to them simultaneously.

  • Map never shrinks. Even if you assign all key values to nil, the underlying array of buckets never lower it's size. A map can only grow and have more buckets; it never shrinks. One solution could be to re-create a copy of the current map at a regular pace. Another solution would be to change the map type to store an array pointer: map[int]*[128]byte.

// Empty map (nil)
var mm map[string]string
// panic: assignment to entry in nil map
// mm["test"] = "ok"

// Сreate map with zero elements
var mm2 map[string]string = map[string]string{}


// map literal
var m1 = map[string]string{
    "Bell Labs": "Hearth of CS",
    "Google": "Best employee nowadays",
}

m2 = make(map[string]string)
m2["Bell Labs"] = "Hearth of CS"
m2["Bell Labs"] // Hearth of CS

var m3 = map[string]Vertex{
    "Bell Labs": Vertex{
        40.68433, -74.39967,
    },
    "Google": Vertex{
        37.42202, -122.08408,
    },
}

// Shorthand version
var m = map[string]Vertex{
    "Bell Labs": {40.68433, -74.39967},
    "Google":    {37.42202, -122.08408},
}

Можно устанавливать ёмкость при создании хеш-таблиц, но нельзя применять к ним функцию cap().

m := make(map[string]int,99)

Map operations

m[key] = elem
elem = m[key]
elem, ok = m[key]
delete(m, key)

To delete a map entry, use the delete built-in function, whose arguments are the map and the key to be deleted. It's safe to do this even if the key is already absent from the map.

Partial modification of the map is not allowed:

func main() {
	type T struct {
		x int
	}

	var mt = map[string]T{"abc": {123}}
	// Map elements are unaddressable.
	// _ = &mt["abc"] // error
	// Partial modification is not allowed.
	// mt["abc"].x = 456 // error
	// It is ok to replace a map element as a whole.
	mt["abc"] = T{x: 789}
}

Map Ordering

But maps are unordered collections, and there’s no way to predict the order in which the key/value pairs will be returned. Even if you store your key/value pairs in the same order, every iteration over a map could return a different order.

colors := map[string]string{
   "AliceBlue":   "#f0f8ff",
   "Coral":       "#ff7F50",
   "DarkGray":    "#a9a9a9",
   "ForestGreen": "#228b22",
}

// Display all the colors in the map.
for key, value := range colors {
    fmt.Printf("Key: %s  Value: %s\n", key, value)
}

The order of the keys and values varies; some runs may be identical. This is actually a security feature to prevent some attacks on guessing map contents.

struct as map keys

Example: use struct as map key:

type Key struct {
    Path,
    Country string
}
hits := make(map[Key]int)

hits[Key{"/", "vn"}]++

Map as function argument

Passing a map between two functions doesn’t make a copy of the map. In fact, you can pass a map to a function and make changes to the map, and the changes will be reflected by all references to the map.

Last updated