教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 go二维map_Golang使用Map的正确姿势

go二维map_Golang使用Map的正确姿势

发布时间:2022-02-25   编辑:jiaochengji.com
教程集为您提供go二维map,Golang使用Map的正确姿势等资源,欢迎您收藏本站,我们将为您提供最新的go二维map,Golang使用Map的正确姿势资源

初始化后再使用

Golang中,map是引用类型,如切片一样,通过下面的代码声明后指向的是nil,所以千万别直接声明后就使用,新手可能经常会犯如下错误:

var m map[string]string

m["result"] = "result"

由于字典是引用类型,所以当我们仅声明而不初始化一个字典类型的变量的时候,他的值是nil。对值为nil的字段除添加键值对外其他操作都不会引发错误。上面的第一行代码对其进行写入操作,就是对空指针的引用,这将会造成一个painc。所以,得记得用 make函数对其进行分配内存和初始化:

m := make(map[string]string)

并发安全

并发安全也叫线程安全,在并发中出现了数据的丢失,称为并发不安全我们都知道非原子操作的都不是并发安全的,在Golang中map,其读写操作并不保证并发安全。如下面的操作

c := make(map[string]string)

wg := sync.WaitGroup{}

for i := 0; i < 10; i {

wg.Add(1)

go func(n int) {

k, v := strconv.Itoa(n), strconv.Itoa(n)

c[k] = v

wg.Done()

}(i)

}

wg.Wait()

fmt.Println(c)

运行则会出现下面的错误

fatal error: concurrent map writes

你可以通过运行go run --race来对程序进行竞态检测

那么如何解决这个问题呢?

通过锁机制解决并发问题

下面介绍几种常见的并发安全的操作map的方法

sync.Mutex

c := make(map[string]string)

wg := sync.WaitGroup{}

var lock sync.Mutex

for i := 0; i < 10; i {

wg.Add(1)

go func(n int) {

k, v := strconv.Itoa(n), strconv.Itoa(n)

lock.Lock()

c[k] = v

lock.Unlock()

wg.Done()

}(i)

}

wg.Wait()

fmt.Println(c)

当然这里也可以使用读写锁sync.RWMutex,这样并发读多的场景下性能要好。

sync.Map

sync.Map 是官方出品的并发安全的map,他在内部使用了大量的原子操作来存取键和值,并使用了read和dirty二个原生map作为存储介质,具体实现流程可阅读相关源码。

var m sync.Map

//写

m.Store("foo", "hello world")

m.Store("slice", []int{1, 2, 3, 4, 5, 6, 7})

m.Store("int", 123)

//读

m.Load("foo")

m.Load("slice")

m.Load("int")

//删

m.Delete("int")

第三方map包

第三方包的实现都大同小异,基本上都是使用分离锁来实现并发安全的,具体分离锁来实现并发安全的原理可参考下面的延伸阅读

m := cmap.New()

//写

m.Set("foo", "hello world")

m.Set("slice", []int{1, 2, 3, 4, 5, 6, 7})

m.Set("int", 1)

//读

m.Get("foo")

m.Get("slice")

m.Get("int")

m := concurrent.NewConcurrentMap()

m.Put("foo", "hello world")

m.Put("slice", []int{1, 2, 3, 4, 5, 6, 7})

m.Put("int", 1)

//读

m.Get("foo")

m.Get("slice")

m.Get("int")

延伸阅读

本文亦在微信公众号【小道资讯】发布,欢迎扫码关注!

image

到此这篇关于“go二维map_Golang使用Map的正确姿势”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
go二维map_Golang使用Map的正确姿势
go语言:给map上锁
Golang错误和异常处理的正确姿势
go语言坑之for range
Go语言发展历史、核心、特性及学习路线
想系统学习GO语言(Golang
Golang从入门到放弃200618--Map(1)Map的初始化和基本操作
Go 开发关键技术指南 | 为什么你要选择 Go?(内含超全知识大图)
golang异常机制
golang map 详解

[关闭]
~ ~