• for range可以迭代Map,Slice , Array , String , Channel , for range的迭代是复制对象的值, 下面的例子做了进一步说明。
  • 迭代Map
arr :=make(<Map>[int]字符串,0)
arr[1] = "Andy"  
arr[2] = "Bob"  
arr[3] = "Cindy"  
for k,v :=range arr{  
    fmt.Printf("a[%d] = %v  ",k,v)  
}

这里有一点需要注意的是,range 'Map'出来的结果是随机的,将上述代码包装成一个函数做多次遍历后,可以看到结果,下面截取了其中一部分可以直观的看出来:

a[1] = Andy  a[2] = Bob  a[3] = Cindy
a[1] = Andy  a[2] = Bob  a[3] = Cindy
a[3] = Cindy  a[1] = Andy  a[2] = Bob

打印上面代码的地址,可以发现是复制的对象。

arr :=make(<Map>[int]字符串,0)  
arr[1] = "Andy"  
arr[2] = "Bob"  
arr[3] = "Cindy"  
fmt.Printf("%p\n",&arr)  
for _,v :=range arr{  
    fmt.Printf("%p\n",&v)  
}

执行结果:

0xc000080018  
0xc0000401c0  
0xc0000401c0  
0xc0000401c0
  • 迭代切片
arr :=[]int{23,34,45,56,67}  
fmt.Printf("%p\n",&arr)  
for _,v :=range arr{  
    fmt.Printf("%p\n",&v)  
}

执行结果:

0xc00004a420  
0xc0000540a0  
0xc0000540a0  
0xc0000540a0  
0xc0000540a0  
0xc0000540a0

切片这里,打印结果的代码直接省略了,打印出来的地址可以发现是复制对象。

  • 迭代数组
arr :=[5]int{23,34,45,56,67}  
fmt.Printf("%p\n",&arr)  
for _,v :=range arr{  
    fmt.Printf("%p\n",&v)  
}

执行结果:

0xc00007e030  
0xc0000540a0  
0xc0000540a0  
0xc0000540a0  
0xc0000540a0  
0xc0000540a0

数组这里,打印结果的代码直接省略了,打印出来的地址可以发现是复制对象。

  • 迭代字符串
str := "henry 你好! "  
for _,v := range str{  
    fmt.Printf(字符串(v))  
}

执行结果:

h  
e  
n  
r  
y  

你  
好  
!  
 

在迭代字符串中,需要注意的是,for range会尝试去把字符串解析为utf8文本,如果数据中存在非utf8的数据,可以先把字符串转化为byte切片。

  • 迭代Channel
c := make(chan int)  
go func() {  
    c <-1  
    c <-2  
    c <-3  
    close(c)  
}()  
for v := range c {  
    fmt.Println(v)  
}

执行结果:

1  
2  
3

迭代管道的时候,没有下标,只有值遍历。