golang range 的用法

在 Go 语言中,range 关键字用于迭代遍历数组(array)、切片(slice)、映射(map)、字符串(string)和通道(channel)中的元素。它的基本语法和用法如下:


1. 遍历数组/切片

nums := []int{2, 3, 4}

// 同时获取索引和值
for index, value := range nums {
fmt.Printf(“索引: %d, 值: %d\n”, index, value)
}

// 仅获取索引
for index := range nums {
fmt.Printf(“索引: %d\n”, index)
}

// 仅获取值(用 _ 忽略索引)
for _, value := range nums {
fmt.Printf(“值: %d\n”, value)
}


2. 遍历映射(Map)

m := map[string]int{“a”: 1, “b”: 2}

// 遍历键值对
for key, value := range m {
fmt.Printf(“键: %s, 值: %d\n”, key, value)
}

// 仅遍历键
for key := range m {
fmt.Printf(“键: %s\n”, key)
}

// 注意:Map 的遍历顺序是随机的!


3. 遍历字符串

s := “hello”

// 遍历字符串的 Unicode 码点(rune)
for index, char := range s {
fmt.Printf(“索引: %d, Unicode值: %U, 字符: %c\n”, index, char, char)
}

// 输出:
// 索引: 0, Unicode值: U+0068, 字符: h
// 索引: 1, Unicode值: U+0065, 字符: e
// …


4. 遍历通道(Channel)

ch := make(chan int)

go func() {
ch <- 1
ch <- 2
close(ch) // 必须关闭通道,否则 range 会阻塞
}()

// 从通道持续接收值,直到通道关闭
for value := range ch {
fmt.Printf(“值: %d\n”, value)
}


5. 注意事项

  1. 值拷贝
    range 返回的是元素的副本,修改副本不会影响原数据:

    nums := []int{1, 2, 3}
    for _, v := range nums {
    v *= 2 // 不影响原切片
    }
    fmt.Println(nums) // 输出 [1 2 3]

  2. 引用类型陷阱
    如果遍历指针类型的切片,需注意循环变量的生命周期:

    type Data struct{ val int }
    list := []*Data{{1}, {2}, {3}}
    var pointers []*int

    // 错误写法:所有指针指向最后一个元素的地址!
    for _, d := range list {
    pointers = append(pointers, &d.val)
    }

    // 正确写法:用局部变量拷贝
    for i := range list {
    val := list[i].val
    pointers = append(pointers, &val)
    }

  3. 性能优化
    遍历大数组时,直接通过索引访问可能比 range 更高效(但差异通常很小)。


总结

  • range 支持数组、切片、map、字符串和通道的遍历。
  • 返回值形式灵活,可选择性忽略索引或值(用 _)。
  • 遍历 map 时顺序随机,字符串遍历按 Unicode 码点处理,通道遍历需提前关闭。

你可能感兴趣的:(golang,开发语言,后端)