Go语言中范围range的使用小结
一、什么是range
range 是 Go 里 用于遍历数据结构的语法糖,常见用法:
for k, v := range collection {
...
}
它能遍历的对象包括:
- 数组 / 切片
- 字符串
- map
- channel
本质上:每次循环,range 会返回“索引/键 + 值”
二、遍历数组 / 切片(最常用)
arr := []int{10, 20, 30}
for i, v := range arr {
fmt.Println(i, v)
}
输出:
0 10
1 20
2 30
只要值,不要索引
for _, v := range arr {
fmt.Println(v)
}
只要索引
for i := range arr {
fmt.Println(i)
}
三、遍历字符串
s := "你好,go!"
for i, c := range s {
fmt.Printf("index=%d,char=%c\n", i, c)
}输出:
index=0,char=你
index=3,char=好
index=6,char=,
index=9,char=g
index=10,char=o
index=11,char=!
注意:
i:字节索引(不是字符索引)c:rune(Unicode 字符)
对比 Java
| Java | Go |
|---|---|
| char 是 UTF-16 | rune 是 UTF-32 |
| String.length() 不等于字符数 | len(s) 是字节数 |
| 遍历字符较绕 | range 天然支持 Unicode |
遍历中文,Go 用 range 是“正解”
四、遍历 map
m := map[string]int{
"a": 1,
"b": 2,
}
for k, v := range m {
fmt.Println(k, v)
}
重要特性
- map 遍历 无序
- 每次运行顺序可能不一样
- Go 刻意这么设计(防止依赖顺序的 bug)
如果需要有序,需这样处理:
keys := make([]string, 0, len(m))
for k := range m {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
fmt.Println(k, m[k])
}
五、遍历 channel
在并发中很有用
ch := make(chan int)
go func() {
ch <- 1
ch <- 2
close(ch)
}()
for v := range ch {
fmt.Println(v)
}
特点:
- 会 一直阻塞
- 直到
channel被close - 非常适合消费协程产生的数据
六、range 的“值拷贝陷阱”
问题代码
arr := []int{1, 2, 3}
for _, v := range arr {
v = v * 10
}
fmt.Println(arr) // [1 2 3]
为什么没改?
v是 元素的拷贝- 修改
v不影响原数组
正确写法
for i := range arr {
arr[i] *= 10
}
七、什么时候不用 range?
| 场景 | 建议 |
|---|---|
| 需要修改原数组 | 用索引 for |
| 需要精确控制步长 | 用经典 for |
| 性能极限场景 | 手写 for 更可控 |
| 遍历 map 顺序敏感 | 不适合 |
八、总结
Go 的 range = 更安全、更简洁的 for-each,但要记住:
1. 值是拷贝;
2. map 无序;
3. 字符串按 rune。
到此这篇关于Go语言中范围range的使用小结的文章就介绍到这了,更多相关Go range内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
gin通过go build -tags实现json包切换及库分析
这篇文章主要为大家介绍了gin通过go build -tags实现json包切换及库分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2023-09-09
Golang程序漏洞检测器govulncheck的安装和使用
govulncheck 是一个命令行工具,可以帮助 Golang 开发者快速找到项目代码和依赖的模块中的安全漏洞,该工具可以分析源代码和二进制文件,识别代码中对这些漏洞的任何直接或间接调用,本文就给大家介绍一下govulncheck安装和使用,需要的朋友可以参考下2023-09-09


最新评论