for range 在go语言中用于遍历一个可迭代的对象,它可以应用于数组,切片,字典等
它有以下一些用法

遍历数组与切片

1
2
3
4
5
6
7
8
9
10
package main

import "fmt"

func main() {
a := [...]string{"a", "b", "c", "d"}
for i := range a {
fmt.Println("Array item", i, "is", a[i])
}
}

初始化数组时使用[...]string 为初始化一个字符串数组,长度自动计算,如果写成[]string 则为初始化一个切片.

for i := range a 这里是通过遍历数组的下标,i 每次循环下标加1,然后通过 array[i] 的方式获取数组的值,也可以在for range 结构中直接获取数组元素

1
2
3
4
5
6
7
8
9
10
11
package main

import "fmt"


func main() {
a := [...]string{"a", "b", "c", "d"}
for i,v := range a {
fmt.Println("Array item", i, "is", v)
}
}

遍历map

遍历字典也有两种方式,一种是遍历key,一种是同时遍历key和value

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main

import "fmt"

func main() {
var fruits = map[string]int {
"apple": 2,
"banana": 5,
"orange": 8,
}

for f,s := range fruits{
fmt.Println("fruits:",f,"score:",s)
}
for f := range fruits{
fmt.Println("fruits:",f,"score:",fruits[f])
}
}

遍历通道

可以使用for range 来遍历通道,当通道未关闭时,会阻塞的等待,当通道关闭以后,则跳出循环遍历。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main

import "fmt"

func main() {
ch := make(chan int,6)
go setData(ch)
for ele := range ch{
fmt.Println("get data " ,ele)
}
}

func setData(ch chan int) {
for v:=0;v<8;v++{
ch <- v
}
close(ch)
}

如果上面代码中,setData函数中不close(ch) 关闭通道的话,则会发生panic 死锁

上面的for range 遍历通道,如果使用for 循环来写的话是下面这样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import "fmt"

func main() {
ch := make(chan int,6)
go setData(ch)
for{
v,ok := <- ch
if !ok{
break
}
fmt.Println("get data ",v)
}
}

func setData(ch chan int) {
for v:=0;v<8;v++{
ch <- v
}
close(ch)
}