Go Maps
Maps are a mapping data type. There is also a built-in maps module for working with the data type.
Type
Example
// To declare and initialize m := make(map[string]int) m["a"] = 1 m["b"] = 2 // Alternatively... m2 := map[string]int{"a": 1, "b": 2} fmt.Println(m["a"]) //key exists, prints 1 fmt.Println(m["c"]) //key does not exist, prints the zero value c, ok = m["c"] if !ok { //ok indicates if the key exists fmt.Println(c) } delete(m, "a") for key, value := range m { fmt.Printf("%s = %s\n", key, value) }
Range over a Map
The simplest and built-in way to range over a map is:
for key, value := range m { fmt.Printf("%s = %s\n", key, value) }
In certain circumstances, it may be more efficient to import the maps module; see below.
Counter
A map can be used as a counter very easily. Because nonexistent keys return the zero value, it isn't necessary to check for existence.
counter := make(map[string]int) for i = 0; i < len(mylist); i++ { counter[mylist[i]]++ }
Set
A map can be used as a set. The key is to use a value type that does not occupy any space in memory.
set := make(map[string]struct{}) set["a"] = struct{} set["b"] = struct{} delete(set, "a") // Intersection intersect := make(map[string]struct{}) for k, _ := range set { if anotherset[k] { intersect[k] = struct{} } } // Union union := make(map[string]struct{}) for k, _ := range set { union[k] = struct{} } for k, _ := range anotherset { union[k] = struct{} } // In-place union for k, _ := range anotherset { set[k] = struct{} }
Notes
A map has to be either declared with make or initialized with a map literal, because the zero value of a map is nil.
Any comparable type can be used as the key in a map. This includes:
- basic types like strings and integers
- pointers
- structs
- channels
- interfaces
The most notable types not allowed are slices and maps themselves.
Module
The following iteration functions are available. These can be more efficient or appropriate that the built-in method of ranging over a map.
Function |
Return Value |
Example |
maps.All(m) |
iterator |
for key, value := maps.All(m) ... |
maps.Keys(m) |
iterator |
for key := maps.Keys(m) ... |
maps.Values(m) |
iterator |
for value := maps.Values(m) ... |
Note that an iterator is perfect for ranging over, or for passing to another function that is prepared to handle any generic sequence (e.g. slices.Collect), but is not the same as a slice.
There are also the following constructor functions:
maps.Clone(m) for creating a new map from another map
maps.Collect(s) for creating a new map from an iterator of pairs (such as what is created by maps.All(m))
There are also some modification functions.
maps.Copy(dest, src) sets keys and values into a destination map according to a source map
maps.DeleteFunc(m, func) deltes keys programmatically
maps.Insert(m, s) sets keys and values into a map according to an iterator of pairs
There are two functions for checking equality. maps.Equal(m1, m2) uses built-in equality while maps.EqualFunc(m1, m2, func) uses a user-provided function to check equality of values. Keys are checked using built-in equality still.