使用for-range进行循环的时候,发现第一个数字是索引,第二个数字是数值。
package main
import "fmt"
func main(){
s := []int{1,2,3}
for i , q := range s{
fmt.Println("i是几",i)
fmt.Println("集合里面的数据",s[i])
fmt.Println("q里面的数据",q)
}
}
for-range表达式作用于所有的集合类型,包括数组、切片、string、map,
甚至还可以遍历channel。
range作用于数组时,从下标0开始依次遍历数组元素,返回元素的下标和元素值举例
如下:
func RangeArray(){
a:=[3]int{1,2,3}
for i, v:=range a {
fmt.Printf( "index: %d value: %d\n",i,v)
}
}
函数输出:
index :0 value: l
index: 1 value: 2
index: 2 value: 3
range作用于切片时,与数组类似,返回元素的下标和元素值。举例如下:
func Rangeslice(s){
s:=[]int1,2,3}
for i,V:=range s{
fmt.Printf( "index: %d value:%d\n",i,v)
}
}
函数输出:
index: 0 value: l
index: 1 value: 2
index: 2 value: 3
for-range作用于string时
func RangeString(){
s := "Hello"
for i, v:=range s {
fmt.Printf("index: %d, value: 号c\n", i,v)
}
}
输出如下:
index: 0, value: H
index: 1, value: e
index: 2, value: l
index: 3, value; 1
index: 4, value: o
//对于中文汉字来说,每个字符会占用多个字节,此时元素的下标就不是连续的:
func RangeStringUniCode() {
s:="中国"
for i, V:= range s {
fmt.Printf("index: %d, value: %c\n",i,v)
}
}
函数输出:
函数输出:
index: 0, value:中
index: 3, value:国
for-range作用于map
range作用于map时,返回每个元素的key和 value:
func RangeMap() {
m := map[string]string( "animal" : "monkey", "fruit": "apple")
for k,V:=range m{
fmt.Printf("key:%s, value: %s\n",k,v)
}
}
函数可能输出:
key: animal, value: monkey key: fruit, value: apple
也可能输出:
key: fruit, value: apple key: animal, value: monkey
由于map的数据结构本身没有顺序的概念,它仅存储key-value对,所以range分别返回key和 value。
另外,如果遍历过程中修改 map(增加或删除元素),则 range行为是不确定的删除的
元素不可能被遍历到,新加的元素可能遍历不到,总之尽量不要在循环中修改 map。
for-range作用于channel
range作用于channel时,会返回channel中所有的元素。举例如下:
func RangeChannel(){
c:= make(chan string, 2)
c<- "Hello"
c<- "world"
time.AfterFunc(time. Microsecond, funcO){
close(c)
})
for e:= range c{
fmt.Printf( "element: %s\n",e)
}
}
element: Hello
element: World
上面的函数中,channel包含两个元素,range遍历完两个元素后会阻塞等待,直到定时器到期后关闭channel才结束遍历。
相较于数组和切片,channel 中的元素没有下标的概念,所以其最多只能返回一个元素。此外需要格外留意的是,range 会阻塞等待channel 中的数据,直到channel被关闭,同时,如果range作用于值为nil的channel时,则会永久阻塞。