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 时还有其他疑问,欢迎留言讨论。


目录
相关文章
|
2月前
|
存储 JavaScript Java
(Python基础)新时代语言!一起学习Python吧!(四):dict字典和set类型;切片类型、列表生成式;map和reduce迭代器;filter过滤函数、sorted排序函数;lambda函数
dict字典 Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。 我们可以通过声明JS对象一样的方式声明dict
195 1
|
2月前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
197 1
|
4月前
|
Cloud Native 安全 Java
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
295 1
|
4月前
|
Cloud Native Go API
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
394 0
|
4月前
|
Cloud Native Java Go
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
259 0
|
4月前
|
Cloud Native Java 中间件
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
228 0
|
4月前
|
Cloud Native Java Go
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
330 0
|
4月前
|
数据采集 Go API
Go语言实战案例:多协程并发下载网页内容
本文是《Go语言100个实战案例 · 网络与并发篇》第6篇,讲解如何使用 Goroutine 和 Channel 实现多协程并发抓取网页内容,提升网络请求效率。通过实战掌握高并发编程技巧,构建爬虫、内容聚合器等工具,涵盖 WaitGroup、超时控制、错误处理等核心知识点。
|
6月前
|
安全 Java 数据库连接
让我们讲解一下 Map 集合遍历的方式
我是小假 期待与你的下一次相遇 ~
246 43
使用 entrySet 遍历 Map 类集合 KV
使用 entrySet 遍历 Map 类集合 KV

热门文章

最新文章