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]。
}

在这里插入图片描述
 
 
 
 
 

在这里插入图片描述