在 Go 语言中,range
关键字用于迭代数组(array)、切片(slice)、字符串(string)、映射(map)或通道(channel)。它的基本语法和常见用法如下:
1. 基本语法
for key, value := range collection {
// 循环体
}
key
:当前元素的索引(数组/切片/字符串)或键(map)。value
:当前元素的值。collection
:被迭代的集合(如 slice、map、string 等)。
2. 不同数据类型的 range
用法
(1) 遍历数组/切片
nums := []int{10, 20, 30}
// 遍历索引和值
for i, num := range nums {
fmt.Printf("Index: %d, Value: %d\n", i, num)
}
// 只遍历索引
for i := range nums {
fmt.Println("Index:", i)
}
// 只遍历值(用 _ 忽略索引)
for _, num := range nums {
fmt.Println("Value:", num)
}
输出:
Index: 0, Value: 10
Index: 1, Value: 20
Index: 2, Value: 30
(2) 遍历字符串
str := "hello"
// range string -> (index, rune)
for i, char := range str { // char是rune类型(Unicode字符)
fmt.Printf("Pos:%d Char:%c Unicode:%U\n", i, char, char)
}
输出:
Pos:0 Char:h Unicode:U+0068
Pos:1 Char:e Unicode:U+0065
Pos:2 Char:l Unicode:U+006C
...
⚠️ 注意:
char
是rune
类型,代表一个Unicode字符。- UTF-8编码下,某些字符可能占用多个字节。
(3) 遍历 map
m := map[string]int{"a": 1, "b": 2}
// key-value遍历
for k, v := range m {
fmt.Printf("%s -> %d\n", k, v)
}
// Go的map是无序的,每次遍历顺序可能不同!
可能的输出:
a ->1
b ->2
(4) channel上的range
ch := make(chan int)
go func() {
ch <-1
ch <-2
close(ch) //必须关闭,否则range会阻塞等待新数据!
}()
// for-range channel会一直读取直到channel关闭
for val := range ch {
fmt.Println(val)
}
输出:
1
2
3. ⚠️注意事项
场景 | 说明 |
---|---|
修改原数据? | range 返回的是副本,直接修改不会影响原数据。如需修改原数据,需使用索引访问。 |
性能优化? | range slice/map 比传统for循环稍慢一些,但代码更简洁易读。 |
并发安全? | range map 在并发读写时会panic!建议加锁或用sync.Map替代。 |
如果需要更高级的迭代控制,可以结合指针、闭包或自定义迭代器模式实现。
内容由零声教学AI助手提供,问题来源于学员提问