写删读nil map
func main() {
pvcPods := map[string]map[string]string{}
if pvcPods["1"] == nil {
pvcPods["1"] = make(map[string]string)
}
pvcPods["1"]["2"] = "1"
pvcPodNil := map[string]string{}
p1, ok := pvcPodNil["1"]
fmt.Printf("p1=%v, ok=%v\n", p1, ok)
delete(pvcPodNil, "1")
}
运行程序后不会报panic。输出:
p1=, ok=false
定义的pvcPods,一个key为string,value也为map的map类型,先对外层map进行了分配内存;判断如果相应的key对应的value为nil map时,在给内层map分配内存;
定义的pvcPodNil没有初始化,为nil map,直接delete nil map是不会报panic的。
实际上在delete源码可以看到:
// delete内置函数从地图中删除具有指定键(m [key])的元素。如果m为nil或没有此类元素,则delete为无操作。
map几种定义方式的不同
package main
import "fmt"
type tmap map[string]int
func main() {
aa := tmap{}
aa["2"] = 2
va, ok := aa["2"]
fmt.Printf("va=%v, ok=%v\n", va, ok)
bb := map[string]int{}
bb["2"] = 2
va, ok = bb["2"]
fmt.Printf("va=%v, ok=%v\n", va, ok)
var cc map[string]int
cc["2"] = 2
va, ok = cc["2"]
fmt.Printf("va=%v, ok=%v\n", va, ok)
}
输出:
va=2, ok=true
va=2, ok=true
panic: assignment to entry in nil map
goroutine 1 [running]:
main.main()
D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:19 +0x370
前两种都是初始化的map,最后一种用var定义的是没有初始化的map。
并发写map
package main
import (
"strconv"
)
func main() {
m1 := make(map[string]string)
for i := 0; i < 30; i++ {
go func(in int) {
s := strconv.Itoa(in)
m1[s] = s
}(i)
}
}
会报错:concurrent map writes
fatal error: concurrent map writes
goroutine 6 [running]:
runtime.throw(0x47c65c, 0x15)
D:/Program Files/Go/go135/src/runtime/panic.go:774 +0x79 fp=0xc000049f20 sp=0xc000049ef0 pc=0x428859
runtime.mapassign_faststr(0x469380, 0xc000058000, 0x47e499, 0x1, 0x0)
D:/Program Files/Go/go135/src/runtime/map_faststr.go:211 +0x41e fp=0xc000049f88 sp=0xc000049f20 pc=0x40e8ee
main.main.func1(0xc000058000, 0x1)
D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:13 +0x6d fp=0xc000049fd0 sp=0xc000049f88 pc=0x4591dd
runtime.goexit()
D:/Program Files/Go/go135/src/runtime/asm_amd64.s:1357 +0x1 fp=0xc000049fd8 sp=0xc000049fd0 pc=0x44da51
created by main.main
D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11 +0x5d
goroutine 1 [runnable]:
runtime.gopark(0x0, 0x0, 0xc000011008, 0x1)
D:/Program Files/Go/go135/src/runtime/proc.go:287 +0x145
runtime.main()
D:/Program Files/Go/go135/src/runtime/proc.go:222 +0x2b4
runtime.goexit()
D:/Program Files/Go/go135/src/runtime/asm_amd64.s:1357 +0x1
goroutine 29 [runnable]:
main.main.func1(0xc000058000, 0x17)
D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11
created by main.main
D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11 +0x5d
goroutine 30 [runnable]:
main.main.func1(0xc000058000, 0x18)
D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11
created by main.main
D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11 +0x5d
goroutine 31 [runnable]:
main.main.func1(0xc000058000, 0x19)
D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11
created by main.main
D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11 +0x5d
goroutine 32 [runnable]:
main.main.func1(0xc000058000, 0x1a)
D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11
created by main.main
D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11 +0x5d
goroutine 33 [runnable]:
main.main.func1(0xc000058000, 0x1b)
D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11
created by main.main
D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11 +0x5d
goroutine 34 [runnable]:
main.main.func1(0xc000058000, 0x1c)
D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11
created by main.main
D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11 +0x5d
goroutine 35 [runnable]:
main.main.func1(0xc000058000, 0x1d)
D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11
created by main.main
D:/SoftwareAndProgram/program/Go/Development/src/gotools/gotest/main.go:11 +0x5d
并发读map
package main
import (
"fmt"
"time"
)
func main() {
m1 := make(map[string]string)
m1["1"] = "1"
for i := 0; i < 100; i++ {
go func(in int) {
fmt.Printf("m[1]=%v\n", m1["1"])
}(i)
}
time.Sleep(2*time.Second)
}
修改遍历中的map
package main
import (
"fmt"
)
func main() {
m1 := make(map[string]string)
m1["1"] = "1"
m1["2"] = "2"
m1["3"] = "3"
m1["4"] = "4"
m1["5"] = "5"
m1["6"] = "6"
m1["7"] = "7"
m1["8"] = "8"
m1["9"] = "9"
m1["10"] = "10"
i := 0
for k, v := range m1 {
i++
if i == 6 {
m1["11"] = "11"
}
fmt.Printf("%v=%v\n", k, v)
}
}
当i==6时,输出了11
1=1
3=3
4=4
7=7
9=9
2=2
5=5
6=6
8=8
10=10
11=11
当i==8时,没输出11
package main
import (
"fmt"
)
func main() {
m1 := make(map[string]string)
m1["1"] = "1"
m1["2"] = "2"
m1["3"] = "3"
m1["4"] = "4"
m1["5"] = "5"
m1["6"] = "6"
m1["7"] = "7"
m1["8"] = "8"
m1["9"] = "9"
m1["10"] = "10"
i := 0
for k, v := range m1 {
i++
if i == 8 {
m1["11"] = "11"
}
fmt.Printf("%v=%v\n", k, v)
}
}
程序输出,没有输出11
3=3
4=4
8=8
10=10
1=1
2=2
5=5
6=6
7=7
9=9