1.系统自带map和sync.Map的由来
map的使用在GO语言中非常的实用,但是系统自带的map直接使用,如果不涉及到并发读写业务,性能很强大,但是一旦出现并发读写的时候,就不建议使用,除非自己手动的进行加锁控制,不过性能不高,所以go推出了sync.map可以解决这种并发读写的问题。
具体的使用:
方式很简单:
var sm sync.Map
//存储Map
sm.Store(u.age, u)
// 获取数据
user, flag := sm.Load(u.age)
//删除map的数据
sm.Delete(u.age)
测试代码:
type U struct {
name string
age int
}
func Test3(test *testing.T) {
u := U{
name: "Tom",
age: 20,
}
var sm sync.Map
//存储Map
sm.Store(u.age, u)
// 获取数据
user, flag := sm.Load(u.age)
fmt.Println("是否有该值:", flag)
//删除map的数据
sm.Delete(u.age)
// 接收到的数据类型是interface接口类型,不能直接使用user.name等具体的属性
fmt.Println(user)
}
2. 针对上面的sync.map 接收到的值是interface所以需要在业务的开发中引入断言的概念:
类型断言: 简单地说就是对于一个不确定的类型进行判断然后去转换为对应的类型去处理相关的业务。
测试代码:
(1)方式一: 直接进行将获取的不确定类型转为指定的类型,成功后执行相关的业务,不成功提示。(一般用于确定的类型)
// 类型断言方式1 x.(类型)
if u2, ok := user.(U); ok {
fmt.Println(u2.name)
} else {
fmt.Println("类型不匹配")
}
(2)方式二:通过switch先进行多种类型的匹配,匹配到哪种类型就直接进行相关的业务(其实是方式1的升级,可用于多种类型业务匹配)
// 断言方式2 switch 先判断,再进行赋值
switch user.(type) {
case U:
u3, _ := user.(U)
fmt.Println("类型断言获取的用户数据", u3)
default:
fmt.Println("类型不匹配")
}
结合sync.map的代码:
func Test3(test *testing.T) {
u := U{
name: "Tom",
age: 20,
}
var sm sync.Map
//存储Map
sm.Store(u.age, u)
// 获取数据
user, flag := sm.Load(u.age)
fmt.Println("是否有该值:", flag)
//删除map的数据
sm.Delete(u.age)
// 接收到的数据类型是interface接口类型,所以需要对接收的数据进行类型断言
// 类型断言方式1 x.(类型)
if u2, ok := user.(U); ok {
fmt.Println(u2.name)
} else {
fmt.Println("类型不匹配")
}
// 断言方式2 switch 先判断,再进行赋值
switch user.(type) {
case U:
u3, _ := user.(U)
fmt.Println("类型断言获取的用户数据", u3)
default:
fmt.Println("类型不匹配")
}
}