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 < 10000; i++ { m[i] = i } }() //A Go program reads map go func(){ for i := 0; i < 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 < 10000; i++ { m[i] = i } () }() //A Go program reads map go func(){ () for i := 0; i < 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!