90%的Go语言程序员map遍历方式都是错的

简介: 90%的Go语言程序员map遍历方式都是错的

/ Go 语言遍历 map 完全指南 /

map 是 Go 语言内置的一种键值对数据结构,用于存储不重复的键值对数据。要访问 map 的所有元素,需要对 map 进行遍历。遍历 map 是 Go 语言中一项基础但重要的技能。

本文将全面介绍如何遍历 Go 语言中的 map,内容涵盖:

  1. for range 遍历 map
  2. 只遍历 key 或 value
  3. 按照特定顺序遍历
  4. 遍历时删除元素
  5. 安全遍历 map
  6. 性能优化
  7. 应用场景

通过详细的讲解和运行示例,可以全面掌握 Go 语言中遍历 map 的知识要点,以及各种遍历技巧的应用。这将大大提高我们处理 map 类型数据的能力。


1

 

1. for range 遍历 map

for range 语句可以用来遍历 map,语法如下:

for key, value := range map {
  //代码
}

它会返回 map 中的每一个键值对,key 是键,value 是对应的值。

例如:

m := map[string]int{"a": 1, "b": 2}
for k, v := range m {
  fmt.Println(k, v) 
}
// 输出:
// a 1
// b 2

用 range 遍历一个 map 会以随机顺序返回所有键值对。


2

 

2. 只遍历 key 或 value

可以通过只接受一个返回值来只遍历 key 或 value:

只要 key:

for key := range m {
  fmt.Println(k)
}

只要 value:

for _, value := range m {
  fmt.Println(value)
}

使用 _ 空标识符忽略不需要的返回值。


3

 

3. 按顺序遍历

map 的遍历顺序是不确定的,要保证顺序需要额外处理。

一个方法是先将 key 放入切片排序,然后遍历切片:

import "sort"
var m = map[int]string{2: "two", 1:"one"} 
keys := make([]int, 0, len(m))
for k := range m {
  keys = append(keys, k)
}
sort.Ints(keys)
for _, k := range keys {
  fmt.Println(k, m[k]) 
}
// 1 one
// 2 two

遍历时每次都会按照插入的顺序打印。


4

 

4. 遍历时删除元素

可以在遍历 map 的时候实时删除元素:

for k, v := range m {
  if meetCondition(k) {
    delete(m, k)
  }
}

但需要注意的是,删除操作会在下次遍历生效,并不会影响当前循环。

不能在遍历中添加元素,会引起运行时错误。


5

 

5. 安全遍历

对 map 的遍历和写操作不是线程安全的,需要采取措施防止数据竞争。

安全遍历 map 的方法有两种:

  1. 遍历时加锁
    可以用 sync.RWMutex 来保证互斥访问:
mu sync.RWMutex // 声明锁
mu.RLock() 
for k, v := range m {
  // 读取map
}
mu.RUnlock()

2. 遍历 map 的只读副本

通过复制生成只读副本:

mCopy := make(map[string]int) 
for k, v := range m {
  mCopy[k] = v
}
// 遍历mCopy副本

这样可以安全地并发遍历 map。


6

 

6. 性能优化

map 遍历时可以通过以下优化提高性能:

  • 复用变量,避免重复分配内存
  • 预计算 map 长度,避免多次调用 len
  • 将 map 转换为切片,减少哈希计算
  • 按顺序遍历,增加 CPU 缓存命中

优化后的遍历:

length := len(m)
keys := make([]int, length) // 预分配keys长度
i := 0 
for k := range m {
  keys[i] = k
  i++
}

这种顺序遍历方式可以大幅提高性能。


7

 

7. 应用场景

  • 打印 key-value
  • 搜索 value
  • 过滤元素
  • 统计出现频率
  • map 转换处理

例如统计单词出现频率:

freq := make(map[string]int)
for _, w := range words {
  freq[w]++
}
// freq map存储了单词频率

map 遍历功能强大,可以处理 map 转化为其他类型,生成报表等操作。


8

 

总结

本文详细讲解了 Go 语言中遍历 map 的知识,包括基本遍历方法、保序遍历、安全遍历、优化等技巧。充分掌握这些可以使我们更自由地处理 map 类型的数据,发挥 map 的最大价值。如果你在遍历 map 时还有其他疑问,欢迎留言讨论。


目录
相关文章
|
6天前
|
存储 JSON 监控
Viper,一个Go语言配置管理神器!
Viper 是一个功能强大的 Go 语言配置管理库,支持从多种来源读取配置,包括文件、环境变量、远程配置中心等。本文详细介绍了 Viper 的核心特性和使用方法,包括从本地 YAML 文件和 Consul 远程配置中心读取配置的示例。Viper 的多来源配置、动态配置和轻松集成特性使其成为管理复杂应用配置的理想选择。
23 2
|
4天前
|
Go 索引
go语言中的循环语句
【11月更文挑战第4天】
13 2
|
4天前
|
Go C++
go语言中的条件语句
【11月更文挑战第4天】
15 2
|
7天前
|
监控 Go API
Go语言在微服务架构中的应用实践
在微服务架构的浪潮中,Go语言以其简洁、高效和并发处理能力脱颖而出,成为构建微服务的理想选择。本文将探讨Go语言在微服务架构中的应用实践,包括Go语言的特性如何适应微服务架构的需求,以及在实际开发中如何利用Go语言的特性来提高服务的性能和可维护性。我们将通过一个具体的案例分析,展示Go语言在微服务开发中的优势,并讨论在实际应用中可能遇到的挑战和解决方案。
|
4天前
|
Go
go语言中的 跳转语句
【11月更文挑战第4天】
12 4
|
4天前
|
JSON 安全 Go
Go语言中使用JWT鉴权、Token刷新完整示例,拿去直接用!
本文介绍了如何在 Go 语言中使用 Gin 框架实现 JWT 用户认证和安全保护。JWT(JSON Web Token)是一种轻量、高效的认证与授权解决方案,特别适合微服务架构。文章详细讲解了 JWT 的基本概念、结构以及如何在 Gin 中生成、解析和刷新 JWT。通过示例代码,展示了如何在实际项目中应用 JWT,确保用户身份验证和数据安全。完整代码可在 GitHub 仓库中查看。
17 1
|
6天前
|
Go 调度 开发者
探索Go语言中的并发模式:goroutine与channel
在本文中,我们将深入探讨Go语言中的核心并发特性——goroutine和channel。不同于传统的并发模型,Go语言的并发机制以其简洁性和高效性著称。本文将通过实际代码示例,展示如何利用goroutine实现轻量级的并发执行,以及如何通过channel安全地在goroutine之间传递数据。摘要部分将概述这些概念,并提示读者本文将提供哪些具体的技术洞见。
|
Go
Go 语言学习之map
Go 语言学习之map
57 0
|
Go
go语言基础数据结构学习 ---- 字典(map)
go语言基础数据结构学习 ---- 字典(map)
116 0
|
Go
Go——小白学习之map
map的使用,key值唯一,打印出是无序的,注意坐标(key)与数组坐标不一样 定义: m3 := map[int]string{1: "mile", 2: "go"} m3[1] = "litter" m3[3] = "gogogo"    //超出范围,错误 fmt.
962 0