Go 压缩基础知识]同步地图的缺陷与解决方案
最编程
2024-05-18 16:11:27
...
1、存在的问题
- 为了考虑通用性,所有的key和value都是interface{},换言之,我们失去了类型检查提供的安全性而且*更多的使用类型断言,后果:
- 在每次调用API后都小心翼翼地使用类型断言,你的代码里面出现无数的if v,ok=value.(xxType);!ok{}
2、解决方案
2.1 方案一
- 如果有明确类型,一个简单的思路是封装snyc.Map,外部函数限制传给sync.Map的API的参数类型,但是灵活性较差
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讲》附属源代码)
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)
}