上代码, 自己品:
package main
import (
"fmt"
"reflect"
)
func main() {
var i int
var list []string
fmt.Println("int comparable: ", reflect.TypeOf(i).Comparable()) // true
fmt.Println("slice comparable: ", reflect.TypeOf(list).Comparable()) // false
}
package main
import (
"sync"
)
type IntStrMap struct {
// m 不对外暴露, 所以只能使用 IntStrMap, 其成员方法都有明确的类型, 可以规律类型的问题
m sync.Map
}
func (self *IntStrMap) Delete(key int) {
self.m.Delete(key)
}
func (self *IntStrMap) Load(key int) (value string, ok bool) {
v, ok := self.m.Load(key)
if v != nil {
value = v.(string)
}
return
}
func (self *IntStrMap) LoadOrStore(key int, value string) (actual string, loaded bool) {
a, loaded := self.m.LoadOrStore(key, value)
actual = a.(string)
return
}
func (self *IntStrMap) Store(key int, value string) {
self.m.Store(key, value)
}
func (self *IntStrMap) Range(f func(key int, value string) bool) {
self.m.Range(func(key, value interface{}) bool {
return f(key.(int), value.(string))
})
}
package main
import (
"fmt"
"reflect"
"sync"
)
type ConcurrentMap struct {
m sync.Map
keyType reflect.Type
valueType reflect.Type
}
func (self *ConcurrentMap) checkKeyType(key interface{}) (keyType reflect.Type, ok bool) {
if self.keyType == nil {
ok = true
return
}
keyType = reflect.TypeOf(key)
ok = keyType == self.keyType
return
}
func (self *ConcurrentMap) checkValueType(value interface{}) (valueType reflect.Type, ok bool) {
if self.valueType == nil {
ok = true
return
}
valueType = reflect.TypeOf(value)
ok = valueType == self.valueType
return
}
func (self *ConcurrentMap) checkStore(key interface{}, value interface{}) {
// 不一定非要引发 panic, 也可以增加返回值来告知调用方, 或者在结构体定义一个字段
if self.keyType == nil {
keyType := reflect.TypeOf(key)
if !keyType.Comparable() {
panic(fmt.Errorf("错误的 key 类型: %v", keyType))
}
self.keyType = keyType
} else if keyType, ok := self.checkKeyType(key); !ok {
panic(fmt.Errorf("错误的 key 类型: %v", keyType))
}
if self.valueType == nil {
self.valueType = reflect.TypeOf(value)
} else if valueType, ok := self.checkValueType(value); !ok {
panic(fmt.Errorf("错误的 value 类型: %v", valueType))
}
}
func (self *ConcurrentMap) Delete(key interface{}) {
if keyType, ok := self.checkKeyType(key); !ok {
panic(fmt.Errorf("错误的 key 类型: %v", keyType))
}
self.m.Delete(key)
}
func (self *ConcurrentMap) Load(key interface{}) (value interface{}, ok bool) {
if _, ok = self.checkKeyType(key); !ok {
return
}
return self.m.Load(key)
}
func (self *ConcurrentMap) LoadOrStore(key interface{}, value interface{}) (actual interface{}, loaded bool) {
self.checkStore(key, value)
return self.m.LoadOrStore(key, value)
}
func (self *ConcurrentMap) Store(key interface{}, value interface{}) {
self.checkStore(key, value)
self.m.Store(key, value)
}
func (self *ConcurrentMap) Range(f func(key interface{}, value interface{}) bool) {
self.m.Range(f)
}
func main() {
cmap := ConcurrentMap{}
cmap.Delete(3)
cmap.Load("abc")
fmt.Println(cmap.keyType, cmap.valueType) //
actual, loaded := cmap.LoadOrStore(3, "abc-efg")
fmt.Println("actual: ", actual) // abc-efg
fmt.Println("loaded: ", loaded) // false
fmt.Println(cmap.keyType, cmap.valueType) // int string
cmap.Store(3, "abc")
value, ok := cmap.Load(3)
fmt.Println("value: ", value) // abc
fmt.Println("ok: ", ok) // true
actual, loaded = cmap.LoadOrStore(3, "efg")
fmt.Println("actual: ", actual) // abc
fmt.Println("loaded: ", loaded) // true
value, ok = cmap.Load("abc")
fmt.Println("value: ", value) //
fmt.Println("ok: ", ok) // false
cmap.Delete("abc") // panic: 错误的 key 类型: string
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)