Go语言映射内部实现及基础功能实战
本篇文章给大家分享《Go语言映射内部实现及基础功能实战》,覆盖了Golang的常见基础知识,其实一个语言的全部知识点一篇文章是不可能说完的,但希望通过这些问题,让读者对自己的掌握程度有一定的认识(B 数),从而弥补自己的不足,更好的掌握它。

写在前面
嗯,学习GO,所以有了这篇文章博文内容为《GO语言实战》读书笔记之一主要涉及映射相关知识
你要爱就要像一个痴情的恋人那样去爱,像一个忘死的梦者那样去爱,视他人之疑目如盏盏鬼火,大胆去走你的夜路。——史铁生《病隙碎笔》
映射的内部实现和基础功能
映射是一种数据结构,是用于存储一系列无序的键值对。类比Java里的Map,Python里的字典,可以理解为以哈希值做索引,期望索引可以在一定的连续内存范围内的类似数组的数据结构。
映射里基于键来存储值。映射功能强大的地方是,能够基于键快速检索数据。键就像索引一样,指向与该键关联的值。
内部实现
映射是一个集合,可以使用类似处理数组和切片的方式迭代映射中的元素。但映射是无序的集合,无序的原因是映射的实现使用了散列表.
映射的散列表包含一组桶。
在存储、删除或者查找键值对的时候,所有操作都要先选择一个桶。把操作映射时指定的键传给映射的散列函数,就能选中对应的桶。
这个散列函数的目的是生成一个索引,这个索引最终将键值对分布到所有可用的桶里。对 Go 语言的映射来说,生成的散列键的一部分,具体来说是低位(LOB),被用来选择桶。

桶的内部实现。映射使用两个数据结构来存储数据,
第一个是数组,内部存储用于选择桶的散列键的高八位值。用于区分每个键值对要存在桶里的那一项。第二个是字节数组,用于存储键值对。该字节数组先依次存储了这个桶里所有的键,之后依次存储了这个桶里所有的值。实现这种键值对的存储方式目的在于减少每个桶所需的内存。
映射存储的增加,索引分布越均匀,访问键值对的速度就越快,随着映射存储的增加,索引分布越均匀,访问键值对的速度就越快。映射通过合理数量的桶来平衡键值对的分布
创建和初始化
Go 语言中有很多种方法可以创建并初始化映射,可以使用内置的make 函数,也可以使用映射字面量。
package main
import (
"fmt"
)
func main() {
// 创建一个映射,键的类型是 string,值的类型是 int
dict := make(map[string]int)
// 创建一个映射,键和值的类型都是 string
// 使用两个键值对初始化映射
dict_ := map[string]string{"Red": "#da1337", "Orange": "#e95a22"}
fmt.Println(dict)
fmt.Print(dict_)
}
======
map[]
map[Orange:#e95a22 Red:#da1337]
创建映射时,更常用的方法是使用映射字面量。映射的初始长度会根据初始化时指定的键值对的数量来确定。
映射的键可以是任何值。这个值的类型可以是内置的类型,也可以是结构类型,只要这个值可以使用==运算符做比较
切片、函数以及包含切片的结构类型由于具有引用语义,不能作为映射的键,使用这些类型会造成编译错误
package main
import (
"fmt"
)
func main() {
// 创建一个映射,使用字符串切片作为映射的键
dict := map[[]string]int{}
fmt.Println(dict)
}
====
[Running] go run "d:\GolandProjects\code-master\demo\hello.go"
# command-line-arguments
demo\hello.go:10:45: duplicate key "Red" in map literal
previous key at demo\hello.go:10:28
[Done] exited with code=2 in 0.902 seconds
声明一个存储字符串切片的映射
// 创建一个映射,使用字符串切片作为值
dict := map[int][]string{}
使用映射
键值对赋值给映射,是通过指定适当类型的键并给这个键赋一个值来完成的
为映射赋值
// 创建一个空映射,用来存储颜色以及颜色对应的十六进制代码
colors := map[string]string{}
// 将 Red 的代码加入到映射
colors["Red"] = "#da1337"
可以通过声明一个未初始化的映射来创建一个值为nil的映射,不能用于存储键值对.
// 创建一个空映射,用来存储颜色以及颜色对应的十六进制代码
colors := map[string]string{}
// 将 Red 的代码加入到映射
colors["Red"] = "#da1337"
从映射取值时有两个选择:
第一个选择是,可以同时获得值,以及一个表示这个键是否存在的标志,
从映射获取值并判断键是否存在
// 获取键 Blue 对应的值
value := colors["Blue"]
// 这个键存在吗?
if value != "" {
fmt.Println(value)
}
另一个选择是,只返回键对应的值,然后通过判断这个值是不是零值来确定键是否存在
从映射获取值,并通过该值判断键是否存在
// 获取键 Blue 对应的值
value := colors["Blue"]
// 这个键存在吗?
if value != "" {
fmt.Println(value)
}
在Go语言里,通过键来索引映射时,即便这个键不存在也总会返回一个值。在这种情况下,返回的是该值对应的类型的零值
迭代映射里的所有值和迭代数组或切片一样,使用关键字 range
使用range 迭代映射
// 创建一个映射,存储颜色以及颜色对应的十六进制代码colors := map[string]string{"AliceBlue": "#f0f8ff","Coral": "#ff7F50","DarkGray": "#a9a9a9","ForestGreen": "#228b22",}// 显示映射里的所有颜色for key, value := range colors {fmt.Printf("Key: %s Value: %s\n", key, value)}// 创建一个映射,存储颜色以及颜色对应的十六进制代码
colors := map[string]string{
"AliceBlue": "#f0f8ff",
"Coral": "#ff7F50",
"DarkGray": "#a9a9a9",
"ForestGreen": "#228b22",
}
// 显示映射里的所有颜色
for key, value := range colors {
fmt.Printf("Key: %s Value: %s\n", key, value)
}
想把一个键值对从映射里删除,就使用内置的delete 函数
从映射中删除一项
// 删除键为 Coral 的键值对delete(colors, "Coral")// 显示映射里的所有颜色for key, value := range colors {fmt.Printf("Key: %s Value: %s\n", key, value)}// 删除键为 Coral 的键值对
delete(colors, "Coral")
// 显示映射里的所有颜色
for key, value := range colors {
fmt.Printf("Key: %s Value: %s\n", key, value)
}
在函数间传递映射
在函数间传递映射并不会制造出该映射的一个副本。实际上,当传递映射给一个函数,并对这个映射做了修改时,所有对这个映射的引用都会察觉到这个修改,这个特性和切片类似,保证可以用很小的成本来复制映射
package mainimport ("fmt")func main() {// 创建一个映射,存储颜色以及颜色对应的十六进制代码colors := map[string]string{"AliceBlue": "#f0f8ff","Coral": "#ff7F50","DarkGray": "#a9a9a9","ForestGreen": "#228b22",}// 显示映射里的所有颜色for key, value := range colors {fmt.Printf("Key: %s Value: %s\n", key, value)}fmt.Println("调用函数来移除指定的键")// 调用函数来移除指定的键removeColor(colors, "Coral")// 显示映射里的所有颜色for key, value := range colors {fmt.Printf("Key: %s Value: %s\n", key, value)}}// removeColor 将指定映射里的键删除func removeColor(colors map[string]string, key string) {delete(colors, key)}package main
import (
"fmt"
)
func main() {
// 创建一个映射,存储颜色以及颜色对应的十六进制代码
colors := map[string]string{
"AliceBlue": "#f0f8ff",
"Coral": "#ff7F50",
"DarkGray": "#a9a9a9",
"ForestGreen": "#228b22",
}
// 显示映射里的所有颜色
for key, value := range colors {
fmt.Printf("Key: %s Value: %s\n", key, value)
}
fmt.Println("调用函数来移除指定的键")
// 调用函数来移除指定的键
removeColor(colors, "Coral")
// 显示映射里的所有颜色
for key, value := range colors {
fmt.Printf("Key: %s Value: %s\n", key, value)
}
}
// removeColor 将指定映射里的键删除
func removeColor(colors map[string]string, key string) {
delete(colors, key)
}
[Running] go run "d:\GolandProjects\code-master\demo\hello.go" Key: Coral Value: #ff7F50 Key: DarkGray Value: #a9a9a9 Key: ForestGreen Value: #228b22 Key: AliceBlue Value: #f0f8ff 调用函数来移除指定的键 Key: AliceBlue Value: #f0f8ff Key: DarkGray Value: #a9a9a9 Key: ForestGreen Value: #228b22 [Done] exited with code=0 in 1.419 seconds
映射的增长没有容量或者任何限制。同时内置函数 len可以用来获取切片或者映射的长度。但是内置函数 cap只能用于切片。

今天关于《Go语言映射内部实现及基础功能实战》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于golang的内容请关注golang学习网公众号!
Golang错误捕获Panic与Recover的使用
- 上一篇
- Golang错误捕获Panic与Recover的使用
- 下一篇
- Go语言特点及基本数据类型使用详解
-
- 害怕的老虎
- 这篇博文真是及时雨啊,好细啊,赞 ??,码起来,关注作者了!希望作者能多写Golang相关的文章。
- 2023-01-07 00:50:18
-
- 追寻的红牛
- 很棒,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,看完之后很有帮助,总算是懂了,感谢老哥分享博文!
- 2023-01-06 07:49:59
-
- Golang · Go教程 | 19小时前 | go标准库 · Go教程 · 字节处理 · 字节切片 Go 1.27 bytes.CutLast bytes.LastIndex 三返回值
- Go 1.27 bytes.CutLast 怎么封装:三返回值与 LastIndex 手写切片对比
- 276浏览 收藏
-
- Golang · Go教程 | 1天前 | 数字签名 · Go教程 · Go安全 · Go 1.27 crypto/ecdsa PrivateKey.Sign SignerOpts 哈希长度
- Go 1.27 ecdsa.PrivateKey.Sign 为什么检查哈希长度:SignerOpts 约束
- 212浏览 收藏
-
- Golang · Go教程 | 1天前 | 标准库 · Go教程 · 整数计算 · math/big RoundingMode Go 1.27 整数除法 Int.Divide
- Go 1.27 math/big.Int Divide 怎么选舍入:Trunc、Floor、Round 与 Ceil
- 202浏览 收藏
-
- Golang · Go教程 | 1天前 | HTTP服务 · Go教程 · 接口设计 · net/http Go 1.27 MaxHeaderValueCount MaxHeaderBytes HTTP安全
- Go 1.27 HTTP 请求头上限怎么设计:MaxHeaderValueCount 与 MaxHeaderBytes 配合
- 376浏览 收藏
-
- Golang · Go教程 | 1天前 | 标准库 · Go教程 · 工具开发 · 错误定位 · 语法分析 · Go 1.27 go/scanner Scanner.End token.Pos 语法诊断
- Go 1.27 go/scanner.Scanner.End 怎么定位 token 末端:起止位置与诊断范围
- 131浏览 收藏
-
- Golang · Go教程 | 1天前 | unsafe · Go教程 · Go升级 · go fix Go 1.27 unsafefuncs unsafe.Add
- Go 1.27 unsafefuncs 怎么改旧代码:函数指针转换的审查边界
- 368浏览 收藏
-
- Golang · Go教程 | 2天前 | go并发 · pprof · 故障排查 · Go教程 · 版本升级 · GODEBUG runtime/pprof Go 1.27 goroutine 标签 tracebacklabels
- Go 1.27 崩溃堆栈为什么多了 goroutine 标签:tracebacklabels 的取舍
- 174浏览 收藏
-
- Golang · Go教程 | 2天前 | 网络编程 · HTTP · go · 性能 · 连接复用 Go 1.27 http.Response.Body Response.Body.Close
- Go 1.27 http.Response.Body 关闭会自动排空什么:连接复用与异常边界
- 311浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- SuperCLUE
- SuperCLUE是权威的中文大语言模型综合评测基准,涵盖语言理解、知识应用、AI Agent智能体及安全性等12项核心能力。通过多轮对话与客观测试,定期发布榜单与技术报告,为模型研发、优化及行业选型提供科学依据。
- 101次使用
-
- C-Eval
- 深入了解C-Eval中文评估套件,涵盖52个学科与4级难度。本文详解其功能特点、Zero-shot/Few-shot使用方法及代码示例,助您全面评测LLM中文理解与泛化能力。
- 19次使用
-
- Gradio
- Gradio是一个用于构建机器学习和数据科学Web应用的开源Python库。支持快速创建交互界面,获Google、Meta等大厂青睐,适合模型演示、部署反馈及调试。
- 101次使用
-
- AutoGPT
- AutoGPT是基于GPT-4的开源AI代理平台,拥有超10万GitHub星标。本文介绍其低代码界面、自动化工作流功能、系统配置要求及安装步骤,助您高效部署和管理AI Agent。
- 106次使用
-
- 腾讯扣叮
- 腾讯扣叮是腾讯推出的6-18岁青少年编程学习平台,依托游戏与AI技术,提供图形化编程、3D创作、虚拟实验室及丰富赛事课程,助力培养计算思维与创新能力。
- 104次使用
-
- Java 性能优化上线清单:从定位、改造到灰度发布
- 2026-06-11 860浏览
-
- Spring Boot 压测验证:Gatling、JMeter 与性能回归门禁
- 2026-06-11 843浏览
-
- Java NMT 非堆内存排查:Direct Buffer、线程栈与 Metaspace 分析
- 2026-06-11 826浏览
-
- Spring Boot 容器内存优化:JVM 堆、非堆与 MaxRAMPercentage
- 2026-06-11 809浏览
-
- Tomcat 连接与线程参数调优:maxThreads、acceptCount 与 KeepAlive
- 2026-06-11 792浏览

