写删读nil map

  1. func main() {
  2. pvcPods := map[string]map[string]string{}
  3. if pvcPods["1"] == nil {
  4. pvcPods["1"] = make(map[string]string)
  5. }
  6. pvcPods["1"]["2"] = "1"
  7. pvcPodNil := map[string]string{}
  8. p1, ok := pvcPodNil["1"]
  9. fmt.Printf("p1=%v, ok=%v\n", p1, ok)
  10. delete(pvcPodNil, "1")
  11. }

运行程序后不会报panic。输出:

  1. p1=, ok=false

定义的pvcPods,一个key为string,value也为map的map类型,先对外层map进行了分配内存;判断如果相应的key对应的value为nil map时,在给内层map分配内存;

定义的pvcPodNil没有初始化,为nil map,直接delete nil map是不会报panic的。

实际上在delete源码可以看到:

  1. // delete内置函数从地图中删除具有指定键(m [key])的元素。如果m为nil或没有此类元素,则delete为无操作。

map几种定义方式的不同

  1. package main
  2. import "fmt"
  3. type tmap map[string]int
  4. func main() {
  5. aa := tmap{}
  6. aa["2"] = 2
  7. va, ok := aa["2"]
  8. fmt.Printf("va=%v, ok=%v\n", va, ok)
  9. bb := map[string]int{}
  10. bb["2"] = 2
  11. va, ok = bb["2"]
  12. fmt.Printf("va=%v, ok=%v\n", va, ok)
  13. var cc map[string]int
  14. cc["2"] = 2
  15. va, ok = cc["2"]
  16. fmt.Printf("va=%v, ok=%v\n", va, ok)
  17. }

输出:

  1. va=2, ok=true
  2. va=2, ok=true
  3. panic: assignment to entry in nil map
  4. goroutine 1 [running]:
  5. main.main()
  6. D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:19 +0x370

前两种都是初始化的map,最后一种用var定义的是没有初始化的map。

并发写map

  1. package main
  2. import (
  3. "strconv"
  4. )
  5. func main() {
  6. m1 := make(map[string]string)
  7. for i := 0; i < 30; i++ {
  8. go func(in int) {
  9. s := strconv.Itoa(in)
  10. m1[s] = s
  11. }(i)
  12. }
  13. }

会报错:concurrent map writes

  1. fatal error: concurrent map writes
  2. goroutine 6 [running]:
  3. runtime.throw(0x47c65c, 0x15)
  4. D:/Program Files/Go/go135/src/runtime/panic.go:774 +0x79 fp=0xc000049f20 sp=0xc000049ef0 pc=0x428859
  5. runtime.mapassign_faststr(0x469380, 0xc000058000, 0x47e499, 0x1, 0x0)
  6. D:/Program Files/Go/go135/src/runtime/map_faststr.go:211 +0x41e fp=0xc000049f88 sp=0xc000049f20 pc=0x40e8ee
  7. main.main.func1(0xc000058000, 0x1)
  8. D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:13 +0x6d fp=0xc000049fd0 sp=0xc000049f88 pc=0x4591dd
  9. runtime.goexit()
  10. D:/Program Files/Go/go135/src/runtime/asm_amd64.s:1357 +0x1 fp=0xc000049fd8 sp=0xc000049fd0 pc=0x44da51
  11. created by main.main
  12. D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11 +0x5d
  13. goroutine 1 [runnable]:
  14. runtime.gopark(0x0, 0x0, 0xc000011008, 0x1)
  15. D:/Program Files/Go/go135/src/runtime/proc.go:287 +0x145
  16. runtime.main()
  17. D:/Program Files/Go/go135/src/runtime/proc.go:222 +0x2b4
  18. runtime.goexit()
  19. D:/Program Files/Go/go135/src/runtime/asm_amd64.s:1357 +0x1
  20. goroutine 29 [runnable]:
  21. main.main.func1(0xc000058000, 0x17)
  22. D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11
  23. created by main.main
  24. D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11 +0x5d
  25. goroutine 30 [runnable]:
  26. main.main.func1(0xc000058000, 0x18)
  27. D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11
  28. created by main.main
  29. D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11 +0x5d
  30. goroutine 31 [runnable]:
  31. main.main.func1(0xc000058000, 0x19)
  32. D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11
  33. created by main.main
  34. D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11 +0x5d
  35. goroutine 32 [runnable]:
  36. main.main.func1(0xc000058000, 0x1a)
  37. D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11
  38. created by main.main
  39. D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11 +0x5d
  40. goroutine 33 [runnable]:
  41. main.main.func1(0xc000058000, 0x1b)
  42. D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11
  43. created by main.main
  44. D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11 +0x5d
  45. goroutine 34 [runnable]:
  46. main.main.func1(0xc000058000, 0x1c)
  47. D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11
  48. created by main.main
  49. D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11 +0x5d
  50. goroutine 35 [runnable]:
  51. main.main.func1(0xc000058000, 0x1d)
  52. D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11
  53. created by main.main
  54. D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11 +0x5d

并发读map

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. func main() {
  7. m1 := make(map[string]string)
  8. m1["1"] = "1"
  9. for i := 0; i < 100; i++ {
  10. go func(in int) {
  11. fmt.Printf("m[1]=%v\n", m1["1"])
  12. }(i)
  13. }
  14. time.Sleep(2*time.Second)
  15. }

运行程序并不会报异常。

修改遍历中的map

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. m1 := make(map[string]string)
  7. m1["1"] = "1"
  8. m1["2"] = "2"
  9. m1["3"] = "3"
  10. m1["4"] = "4"
  11. m1["5"] = "5"
  12. m1["6"] = "6"
  13. m1["7"] = "7"
  14. m1["8"] = "8"
  15. m1["9"] = "9"
  16. m1["10"] = "10"
  17. i := 0
  18. for k, v := range m1 {
  19. i++
  20. if i == 6 {
  21. m1["11"] = "11"
  22. }
  23. fmt.Printf("%v=%v\n", k, v)
  24. }
  25. }

当i==6时,输出了11

  1. 1=1
  2. 3=3
  3. 4=4
  4. 7=7
  5. 9=9
  6. 2=2
  7. 5=5
  8. 6=6
  9. 8=8
  10. 10=10
  11. 11=11

当i==8时,没输出11

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. m1 := make(map[string]string)
  7. m1["1"] = "1"
  8. m1["2"] = "2"
  9. m1["3"] = "3"
  10. m1["4"] = "4"
  11. m1["5"] = "5"
  12. m1["6"] = "6"
  13. m1["7"] = "7"
  14. m1["8"] = "8"
  15. m1["9"] = "9"
  16. m1["10"] = "10"
  17. i := 0
  18. for k, v := range m1 {
  19. i++
  20. if i == 8 {
  21. m1["11"] = "11"
  22. }
  23. fmt.Printf("%v=%v\n", k, v)
  24. }
  25. }

程序输出,没有输出11

  1. 3=3
  2. 4=4
  3. 8=8
  4. 10=10
  5. 1=1
  6. 2=2
  7. 5=5
  8. 6=6
  9. 7=7
  10. 9=9