【Go夯实基础】syncMap的缺陷与解决方法

1、存在的问题

  • 为了考虑通用性,所有的key和value都是interface{},换言之,我们失去了类型检查提供的安全性而且被迫更多的使用类型断言,后果:
    • 在每次调用API后都小心翼翼地使用类型断言,你的代码里面出现无数的if v,ok=value.(xxType);!ok{}

2、解决方案

2.1 方案一

  • 如果有明确类型,一个简单的思路是封装snyc.Map,外部函数限制传给sync.Map的API的参数类型,但是灵活性较差
1
2
3
4
5
6
7
8
9
10
11
12
13
go复制代码type StringMap struct{
m sync.Map
}
func (s *StringMap) Store(key,value string){
s.m.Store(key,value)
}
func (s *StringMap) Load(key string)(value string,ok bool){
v, ok := s.m.Load(key)
if v != nil {
value = v.(string)
}
return
}

2.2 方案二

  • 用反射来帮助我们做类型检查(下面的代码来自于极客时间《go核心36讲》附属源代码)
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
go复制代码type ConcurrentMap struct {
m sync.Map
keyType reflect.Type
valueType reflect.Type
}

//创建ConcurrentMap
func NewConcurrentMap(keyType, valueType reflect.Type) (*ConcurrentMap, error) {
if keyType == nil {
return nil, errors.New("nil key type")
}
if !keyType.Comparable() {
return nil, fmt.Errorf("incomparable key type: %s", keyType)
}
if valueType == nil {
return nil, errors.New("nil value type")
}
cMap := &ConcurrentMap{
keyType: keyType,
valueType: valueType,
}
return cMap, nil
}

func (cMap *ConcurrentMap) Delete(key interface{}) {
//传入的参数类型必须要和 初始化的ConcurrentMap的key类型一致
if reflect.TypeOf(key) != cMap.keyType {
return
}
cMap.m.Delete(key)
}

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%