range 用于在循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)中的元素。数组、切片中 range 返回元素的索引和索引对应的值,集合中返回 key-value 对。
格式:
for key, value := range data {
}
可以忽略不想要的返回值,也可以用 “_” 这个特殊变量。
func main() {
m := map[string]int{"a": 1, "b": 2}
for k, v := range m {
fmt.Println(k, v)
}
s := "abc"
// 忽略value
for i := range s {
fmt.Println(i)
}
// 忽略index
for _, c := range s {
fmt.Printf("%c\n", c)
}
// 忽略全部返回值,仅迭代。
for range s {
fmt.Println("仅迭代")
}
}
注意:使用 range 会复制对象,举例。
func main() {
a := [3]int{0, 1, 2} //数组
for i, v := range a { // index、value 都是从a数组的复制品中取出。
if i == 0 { // 在修改前先修改原数组。
a[1], a[2] = 999, 999
fmt.Println(a) // 确认修改有效,输出 [0, 999, 999]。
}
a[i] = v + 100 // 使用复制品中取出的 value 修改原数组。
}
fmt.Println(a) // 输出 [100, 101, 102]。
}
range遍历引用类型时,底层数据不会被复制,举例:
func main() {
a := []int{0, 1, 2} //slice
for i, v := range a {
if i == 0 { // 在修改前先修改原数组。
a[1], a[2] = 999, 999
fmt.Println(a) // 确认修改有效,输出 [0, 999, 999]。
}
a[i] = v + 100
}
fmt.Println(a) // 输出 [100, 1099, 1099]。
}