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
12
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
19
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
23
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)
}