跟老男孩学GO语言之range 循环语句
老男孩IT教育
常见问题
2021年5月31日 17:04
Go 语言中 range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。在数组和切片中它返回元素的索引和索引对应的值,在集合中返回 key-value 对的 key 值。
Go 语言中 range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。在数组和切片中它返回元素的索引和索引对应的值,在集合中返回 key-value 对的 key 值。
字符串遍历
1、for range 英文字符串,key 值按照+1顺序递增
package main
import (
"fmt"
)
func main() {
var str string = "oldboy"
for k, v := range str {
fmt.Println(k, string(v))
}
}
2、for range 包含中文的字符串,英文字符 key 值按照+1顺序递增,中文字符 key 值按照+3顺序递增
package main
import (
"fmt"
)
func main() {
var str string = "老男孩IT教育,只培养技术精英。"
for k, v := range str {
fmt.Println(k, string(v))
}
}
数组遍历
1、for range 数组程序会复制对象,key、value 都是从复制品中取出
package main
import (
"fmt"
)
func main() {
arr := [5]int{1, 2, 3, 4, 5}
for k, v := range arr {
if k == 0 {
arr[0], arr[1] = 1000, 1000
fmt.Println("修改原数组:", arr)
}
// 使用复制品中取出的 value 修改原数组
arr[k] = v + 100
}
fmt.Println(arr)
}
2、多维数组遍历
package main
import (
"fmt"
)
func main() {
var arr [2][3]int = [2][3]int{{1, 2, 3}, {2, 4, 6}}
for k1, v1 := range arr {
for k2, v2 := range v1 {
fmt.Printf("%d*%d=%d ", k1+1, k2+1, v2)
}
fmt.Printf("\n")
}
}
3、数组遍历值拷贝行为会造成性能问题,建议数组遍历使用引用类型slice,或数组指针。
package main
import "fmt"
func main() {
arr := [5]int{1, 2, 3, 4, 5}
arrP := &arr
for k, _ := range arrP {
if k == 0 {
arrP[0], arrP[1] = 1000, 1000
fmt.Println("修改原数组:", arr)
}
arrP[k] += 100
}
fmt.Println(arr)
}
slice 遍历
将所需数据 copy 到较小的 slice,以便释放底层数组内存
package main
import (
"fmt"
)
func main() {
arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
slice := arr[:]
for key, value := range slice {
fmt.Printf("key: %v , value : %v\n", key, value)
}
}
map 遍历
map 遍历不能保证迭代返回次序,通常是随机结果,具体和版本实现有关。
package main
import (
"fmt"
)
func main() {
m := map[int]string{
1: "oldboy",
2: "Linux",
3: "Golang",
4: "Python",
5: "Java",
6: "DBA",
}
for k, v := range m {
fmt.Printf("%d => %s \n", k, v)
}
}
channel 遍历
package main
import "fmt"
func main() {
var ch chan int
ch = make(chan int, 10)
for i := 0; i < 10; i++ {
ch <- i
}
close(ch)
for v := range ch {
fmt.Println(v)
}
}
注意:如果没有 close() 因为存入管道10个数字,然后无限取数据,在取出来第10个数据,在次range管道,会dead lock。
推荐阅读:
