SoFunction
Updated on 2025-03-04

Some points to pay attention to when using maps

1. Introduction

map is a convenient and powerful built-in data structure in Golang. It is an unordered group of elements of the same type, and elements are indexed by another type of unique key. Its keys can be types supported by any equality operator, such as integers, floating point numbers, complex numbers, strings, pointers, interfaces (as long as their dynamic types support equality judgments), structures, and arrays. Slices cannot be used as mapping keys because their equality is not yet defined. Like slices, maps are reference types. If the map is passed into the function and the content of the map is changed, this modification is also visible to the caller. The uninitialized mapping value is nil.

Examples of use are as follows:

package main

import "fmt"

func main() {
    nameAge := make(map[string]int)
    nameAge["bob"] = 18           //increase    nameAge["tom"] = 16           //increase    delete(nameAge, "bob")         //delete    nameAge["tom"] = 19           //change    v := nameAge["tom"]           //check    ("v=",v)
    v, ok := nameAge["tom"]         // Check, recommended usage    if ok { 
      ("v=",v,"ok=",ok)
    }  
    for k, v :=range nameAge {   		//Travel        (k, v)
    }  
}

Output result:

v= 19
v= 19 ok= true
tom 19

2. Things to note

2.1 The element of map is not addressable

The element in the map is not a variable, but a value. Therefore, we cannot access the map elements.

var m = map[int]int {
	0 : 0,
	1: 1,
}

func main() {
    (&m[0])
}

Run error:

cannot take the address of m[0]

Therefore, when the element of map is a value of the structure type, it is impossible to directly modify the field value in the structure. Examine the following example:

package main

import (
    "fmt"
)

type person struct {
  name  string
  age  byte
  isDead bool
}

func whoIsDead(personMap map[string]person) {
  for name, _ := range personMap {
    if personMap[name].age < 50 {
      personMap[name].isDead = true
    }  
  }  
}

func main() {
  p1 := person{name: "zzy", age: 100}
  p2 := person{name: "dj", age: 99} 
  p3 := person{name: "px", age: 20} 
  personMap := map[string]person{
    : p1, 
    : p2, 
    : p3, 
  }  
  whoIsDead(personMap)
  
  for _, v :=range personMap {
    if  {
      ("%s is dead\n", )
    }  
  }  
}

Compilation error:

cannot assign to struct field personMap[name].isDead in map

The reason is that the map element cannot be addressed, which means that personMap[name] can be obtained, but it cannot be modified. There are two solutions: one is to use the pointer type of the map value to Strct, and the other is to use temporary variables, and then set them back after each time.

(1) Change the element in the map to a pointer to struct.

package main

import (
    "fmt"
)

type person struct {
  name  string
  age  byte
  isDead bool
}

func whoIsDead(people map[string]*person) {
  for name, _ := range people {
    if people[name].age < 50 {
      people[name].isDead = true
    }  
  }  
}

func main() {
  p1 := &person{name: "zzy", age: 100}
  p2 := &person{name: "dj", age: 99} 
  p3 := &person{name: "px", age: 20} 
  personMap := map[string]*person {
    : p1, 
    : p2, 
    : p3, 
  }  
  whoIsDead(personMap)
  
    for _, v :=range personMap {
        if  {
            ("%s is dead\n", )
        }  
    }  
}

Output result:

px is dead

(2) Use temporary variables to overwrite the original element.

package main

import (
    "fmt"
)

type person struct {
  name  string
  age  byte
  isDead bool
}

func whoIsDead(people map[string]person) {
  for name, _ := range people {
    if people[name].age < 50 {
      tmp := people[name]
       = true
      people[name] = tmp 
    }  
  }  
}

func main() {
  p1 := person{name: "zzy", age: 100}
  p2 := person{name: "dj", age: 99} 
  p3 := person{name: "px", age: 20} 
  personMap := map[string]person {
    : p1, 
    : p2, 
    : p3, 
  }  
  whoIsDead(personMap)
  
    for _, v :=range personMap {
        if  {
            ("%s is dead\n", )
        }  
    }  
}

Output result:

px is dead

2.2 Map concurrent reading and writing problems

Shared maps need to be locked during concurrent reading and writing. Let's look at the error example first:

package main

import (
    "fmt"
    "time"
)

var m = make(map[int]int)

func main() {
    //A Go program writes map    go func(){
        for i := 0; i &lt; 10000; i++ {
            m[i] = i  
        }  
    }() 

    //A Go program reads map    go func(){
        for i := 0; i &lt; 10000; i++ { 
            (m[i])  
        }  
    }() 
    (*20)
}

Run error:

fatal error: concurrent map read and map write

Mutexual access can be achieved using read-write lock().

package main

import (
    "fmt"
    "time"
    "sync"
)

var m = make(map[int]int)
var rwMutex 

func main() {
    //A Go program writes map    go func(){
        ()
        for i := 0; i &lt; 10000; i++ {
            m[i] = i  
        }  
        ()
    }() 

    //A Go program reads map    go func(){
        ()
        for i := 0; i &lt; 10000; i++ { 
            (m[i])  
        }  
        ()
    }() 
    (*20)
}

Normal operation output:

0
1
...
9999

The above is the detailed content of a few points that Golang needs to pay attention to when using map. For more information about golang map, please pay attention to my other related articles!