Accessing map


Map is a reference type which points to a hash table, and you can use it to construct a “key-value” database which is very handy in practice programming. E.g., the following code will calculate the count of every element in a slice:

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. s := []int{1, 1, 2, 2, 3, 3, 3}
  7. m := make(map[int]int)
  8. for _, v := range s {
  9. m[v]++
  10. }
  11. for key, value := range m {
  12. fmt.Printf("%d occurs %d times\n", key, value)
  13. }
  14. }

The output is like this:

  1. 3 occurs 3 times
  2. 1 occurs 2 times
  3. 2 occurs 2 times

Moreover, according to Go spec: “A map is an unordered group of elements of one type, called the element type, indexed by a set of unique keys of another type, called the key type.”. So if you run the above program another time, the output may be different:

  1. 2 occurs 2 times
  2. 3 occurs 3 times
  3. 1 occurs 2 times

You must not presume the element order of a map.

The key type of the map must can be compared with “==“ operator: the built-in types, such as int, string, etc, satisfy this requirement; while slice not. For struct type, if its members all can be compared by “==“ operator, then this struct can also be used as key.

When you access a non-exist key of the map, the map will return the nil value of the element. I.e.:

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. m := make(map[int]bool)
  7. m[0] = false
  8. m[1] = true
  9. fmt.Println(m[0], m[1], m[2])
  10. }

The output is:

  1. false true false

the value of m[0] and m[2] are both false, so you can’t discriminate whether the key is really in map or not. The solution is to use “comma ok” method:

  1. value, ok := map[key]

if the key does exit, ok will be true; else ok will be false.

Sometimes, you may not care the values of the map, and use map just as a set. In this case, you can declare the value type as an empty struct: struct{}. An example is like this:

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func check(m map[int]struct{}, k int) {
  6. if _, ok := m[k]; ok {
  7. fmt.Printf("%d is a valid key\n", k)
  8. }
  9. }
  10. func main() {
  11. m := make(map[int]struct{})
  12. m[0] = struct{}{}
  13. m[1] = struct{}{}
  14. for i := 0; i <=2; i++ {
  15. check(m, i)
  16. }
  17. }

The output is:

  1. 0 is a valid key
  2. 1 is a valid key

Using built-in delete function, you can remove an entry in the map, even the key doesn’t exist:

  1. delete(map, key)

References:
Effective Go;
The Go Programming Language Specification;
The Go Programming Language.