Go 语言范围(Range) - GO教程

Go 语言范围(Range)

Go 语言中 range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。在数组和切片中它返回元素的索引和索引对应的值,在集合中返回 key-value 对。

for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环。格式如下:

for key, value := range oldMap {

    newMap[key] = value

}

以上代码中的 key 和 value 是可以省略。

如果只想读取 key,格式如下:

for key := range oldMap

或者这样:

for key, _ := range oldMap

如果只想读取 value,格式如下:

for _, value := range oldMap

实例

数组和切片

遍历简单的切片, 2**%d 的结果为 2 对应的次方数:

示例代码
packagemainimport"fmt"// 声明一个包含 2 的幂次方的切片varpow=[]int{1,2,4,8,16,32,64,128}funcmain(){// 遍历 pow 切片,i 是索引,v 是值fori,v:=rangepow{// 打印 2 的 i 次方等于 vfmt.Printf("2**%d = %d\n",i,v)}}

以上实例运行输出结果为:


2**0 = 1

2**1 = 2

2**2 = 4

2**3 = 8

2**4 = 16

2**5 = 32

2**6 = 64

2**7 = 128

字符串

range 迭代字符串时,返回每个字符的索引和 Unicode 代码点(rune)。

示例代码
packagemainimport"fmt"funcmain(){fori,c:=range"hello"{fmt.Printf("index: %d, char: %c\n",i,c)}}

以上实例运行输出结果为:

index: 0, char: h

index: 1, char: e

index: 2, char: l

index: 3, char: l

index: 4, char: o

映射(Map)

for 循环的 range 格式可以省略 key 和 value,如下实例:

示例代码
packagemainimport"fmt"funcmain(){// 创建一个空的 map,key 是 int 类型,value 是 float32 类型map1:=make(map[int]float32)// 向 map1 中添加 key-value 对map1[1]=1.0map1[2]=2.0map1[3]=3.0map1[4]=4.0// 遍历 map1,读取 key 和 valueforkey,value:=rangemap1{// 打印 key 和 valuefmt.Printf("key is: %d - value is: %f\n",key,value)}// 遍历 map1,只读取 keyforkey:=rangemap1{// 打印 keyfmt.Printf("key is: %d\n",key)}// 遍历 map1,只读取 valuefor_,value:=rangemap1{// 打印 valuefmt.Printf("value is: %f\n",value)}}

以上实例运行输出结果为:

key is: 4 - value is: 4.000000

key is: 1 - value is: 1.000000

key is: 2 - value is: 2.000000

key is: 3 - value is: 3.000000

key is: 1

key is: 2

key is: 3

key is: 4

value is: 1.000000

value is: 2.000000

value is: 3.000000

value is: 4.000000

通道(Channel)

range 遍历从通道接收的值,直到通道关闭。

示例代码
packagemainimport"fmt"funcmain(){ch:=make(chanint,2)ch <-1ch <-2close(ch)forv:=rangech{fmt.Println(v)}}

以上实例运行输出结果为:

1

2

忽略值

在遍历时可以使用 _ 来忽略索引或值。

示例代码
packagemainimport"fmt"funcmain(){nums:=[]int{2,3,4}// 忽略索引for_,num:=rangenums{fmt.Println("value:",num)}// 忽略值fori:=rangenums{fmt.Println("index:",i)}}

以上实例运行输出结果为:

value: 2

value: 3

value: 4

index: 0

index: 1

index: 2

其他

range 遍历其他数据结构:

示例代码
packagemainimport"fmt"funcmain(){//这是我们使用 range 去求一个 slice 的和。使用数组跟这个很类似nums:=[]int{2,3,4}sum:=0for_,num:=rangenums{sum+=num}fmt.Println("sum:",sum)//在数组上使用 range 将传入索引和值两个变量。上面那个例子我们不需要使用该元素的序号,所以我们使用空白符"_"省略了。有时侯我们确实需要知道它的索引。fori,num:=rangenums{ifnum==3{fmt.Println("index:",i)}}//range 也可以用在 map 的键值对上。kvs:=map[string]string{"a":"apple","b":"banana"}fork,v:=rangekvs{fmt.Printf("%s -> %s\n",k,v)}//range也可以用来枚举 Unicode 字符串。第一个参数是字符的索引,第二个是字符(Unicode的值)本身。fori,c:=range"go"{fmt.Println(i,c)}}

以上实例运行输出结果为:


sum: 9

index: 1

a -> apple

b -> banana

0 103

1 111