1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
| package main
import (
"fmt"
"sync"
)
func GetType(d any) string {
switch d.(type) {
case int:
return "int"
case uint:
return "uint"
case string:
return "string"
case float32:
return "float32"
case float64:
return "float64"
default:
return "未知类型"
}
}
func main() {
defer func() {
if r := recover(); r != nil {
fmt.Println("panic", r)
}
}()
var m sync.Map
fmt.Printf("%T\n", m) // sync.Map
fmt.Printf("%v\n", m) // {{0 0} {[] {} <nil>} map[] 0}
fmt.Printf("%#v\n", m) // sync.Map{mu:sync.Mutex{state:0, sema:0x0}, read:atomic.Pointer[sync.readOnly]{_:[0]*sync.readOnly{}, _:atomic.noCopy{}, v:(unsafe.Pointer)(nil)}, dirty:map[interface {}]*sync.entry(nil), misses:0}
// 添加 k=int,v=int 的键值对
m.Store(0, 0)
// 添加 k=int,v=string 的键值对
m.Store(1, "1")
// 添加 k=string,v=int 的键值对
m.Store("2", 2)
// 添加 k=string,v=string 的键值对
m.Store("3", "3")
// 查询
d, ok := m.Load(0)
//var dd int
//dd = d // 编译报错:cannot use d (variable of type any) as int value in assignment: need type assertion
//fmt.Println(dd)
fmt.Printf("%v,%T,%t\n", d, d, ok) // 0,int,true
d, ok = m.Load(1)
fmt.Printf("%v,%T,%t\n", d, d, ok) // 1,string,true
d, ok = m.Load("2")
fmt.Printf("%v,%T,%t\n", d, d, ok) // 2,int,true
d, ok = m.Load("3")
fmt.Printf("%v,%T,%t\n", d, d, ok) // 3,string,true
// 遍历
m.Range(func(k, v any) bool {
kt := GetType(k)
vt := GetType(v)
fmt.Println("键类型是", kt, ",值类型是", vt, " ->", k, ":", v)
return true
})
// 删除
// 删除存在的键
m.Delete(0)
// 删除不存在的键
m.Delete("A")
// 使用 CompareAndDelete 方法
// 对于已经删除的键
fmt.Println(m.CompareAndDelete(0, 1)) // false
// 对于还存在的键,给出的旧值和存储的一致
fmt.Println(m.CompareAndDelete(1, "1")) // true
// 对于还存在的键,给出的旧值和存储的不一致
fmt.Println(m.CompareAndDelete(1, "11")) // false
// 对于还存在的键,给出的旧值和存储的不一致
fmt.Println(m.CompareAndDelete("2", 22)) // false
// 对于还存在的键,给出的旧值和存储的一致
fmt.Println(m.CompareAndDelete("2", 2)) // true
// 再次遍历,会发现只剩下: 一个键值对了
m.Range(func(k, v any) bool {
kt := GetType(k)
vt := GetType(v)
fmt.Println("键类型是", kt, ",值类型是", vt, " ->", k, ":", v)
return true
})
// 使用 LoadOrStore 方法
fmt.Println(m.LoadOrStore(0, 0)) // 0 false
fmt.Println(m.LoadOrStore(1, "1")) // 1 false
fmt.Println(m.LoadOrStore("2", 22)) // 22 false
fmt.Println(m.LoadOrStore("3", "33")) // 3 true <- 注意这里的 33 最终并没有被写入到m中
// 再次遍历
m.Range(func(k, v any) bool {
kt := GetType(k)
vt := GetType(v)
fmt.Println("键类型是", kt, ",值类型是", vt, " ->", k, ":", v)
return true
})
// 使用 LoadAndDelete 方法
fmt.Println(m.LoadAndDelete("3")) // 3 true
fmt.Println(m.LoadAndDelete("3")) // <nil> false
// 使用 CompareAndSwap 方法
fmt.Println(m.CompareAndSwap("3", "", "3")) // false
fmt.Println(m.CompareAndSwap("3", "", "3")) // false
fmt.Println(m.CompareAndSwap("2", 2, 22)) // false
fmt.Println(m.CompareAndSwap("2", 22, 2)) // true
// 再次遍历
m.Range(func(k, v any) bool {
kt := GetType(k)
vt := GetType(v)
fmt.Println("键类型是", kt, ",值类型是", vt, " ->", k, ":", v)
return true
})
}
|