重点
在上篇文章《go基础之map-增和改(二)》已经非常详细的描述了定位key所在的桶以及它所在桶的位置,如果对上篇有所了解之后,该偏博客理解起来就会非常容易。总的来说map的删除主要做了2件事:
- 定位key所在的位置,并且删除key,清除value的内存数据;
- 尝试标记该key所在桶里面的元素为emptyRest,如果该桶处在逸出桶,那么就尝试向前遍历桶的元素为emptyRest。
如果想详细查看源码的注释,可以查看我的GitHub,欢迎批评指正。我的打算是把一些常用的数据结构都分析一遍,如果有志同道合的人,可以联系我。
详细解析
前面系列的文章如果有所了解的话,那这篇文章我就按照重点解析源码了,主要是思路。其实删除算是该map最简单的一个操作了。首先说明下map删除的底层代码是mapdelete_faststr
方法,在runtime/map_faststr.go里面。话不多说上码。
func mapdelete_faststr(t *maptype, h *hmap, ky string) {
if raceenabled && h != nil {
callerpc := getcallerpc()
racewritepc(unsafe.Pointer(h), callerpc, funcPC(mapdelete_faststr))
}
if h == nil || h.count == 0 {
return
}
if h.flags&hashWriting != 0 {
throw("concurrent map writes")
}
key := stringStructOf(&ky)
hash := t.hasher(noescape(unsafe.Pointer(&ky)), uintptr(h.hash0))
// Set hashWriting after calling t.hasher for consistency with mapdelete
h.flags ^= hashWriting
bucket := hash & bucketMa