Runtime:源码解析Golang 的map实现原理

go version 1.15.6

map作为一种常见的 key-value 数据结构,不同语言的实现原理基本差不多。首先在系统里分配一段连接的内存地址作为数组,然后通过对map键进行hash算法(最终将键转换成了一个整型数字)定位到不同的桶bucket(数组的索引位置),然后将值存储到对应的bucket里

map hash算法

理想的情况下是一个bucket存储一个值,即数组的形式,时间复杂度为O(1)。

如果存在键值碰撞的话,可以通过 链表法 或者 开放寻址法 来解决。

Continue reading

golang中的map数据类型操作实例


package main

import (
 "fmt"
)

type stu struct {
 Name string
 Age int
}

func main() {

//声明一个map变量student,键名为string,值为stu
 var student map[string]stu

//给map变量创建值,同时指定最多可以存储5个stu值
 student = make(map[string]stu, 5)

//map元素赋值
 student["stu1"] = stu{"zhao", 25}
 student["stu2"] = stu{"zhang", 28}
 student["stu3"] = stu{"sun", 32}
 student["stu4"] = stu{"li", 40}
 student["stu5"] = stu{}

//上面方式的简写方法
 /* 
student := map[string]stu{
 "stu1": stu{"zhao", 25},
 "stu2": stu{"zhang", 28},
 "stu3": stu{"sun", 32},
 "stu4": stu{"li", 40},
 "stu5": stu{},
 }
*/

//打印map信息
 fmt.Printf("%v\n", student)

//查询一个map值
 s1, ok := student["stu2"]
 if ok {
 fmt.Println("Found stu2, Name:", s1.Name)
 } else {
 fmt.Println("Not Found stu2")
 }

//删除一个map值,如果stu2不存在,则什么也不会发生,但如果传入的map变量的值为nil的话,则会抛出一个 panic 异常
 delete(student, "stu2")

fmt.Printf("%v\n", student)

}

执行结果如下:

go run map.go
[ `go run map.go` | done: 2.3907474s ]
	map[stu1:{zhao 25} stu2:{zhang 28} stu3:{sun 32} stu4:{li 40} stu5:{ 0}]
	Found stu2, Name: zhang
	map[stu1:{zhao 25} stu3:{sun 32} stu4:{li 40} stu5:{ 0}]