這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
一、用法
range類似迭代器,可以遍曆數組,字串,map等等,對象的不同,返回的結果也不同。
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(){ //數組的遍曆 a := [3]int {1, 2, 3} for i, n := range a{ fmt.Println(i, n) } //切片的遍曆 b := []int{2, 3, 4} for i, n := range b{ fmt.Println(i, n) } //map的遍曆 c := map[string]int{"Hello":1, "World":2} for k, v := range c{ fmt.Println(k, v) } }
|
結果:
1 2 3 4 5 6 7 8
|
0 1 1 2 2 3 0 2 1 3 2 4 Hello 1 World 2
|
二、注意事項
1. range會複製對象,而不是不是直接在原對象上操作。
樣本一:
1 2 3 4 5 6 7 8 9
|
package main import "fmt" func main(){ a := [3]int {1, 2, 3} for _, v := range a{ //複製一份a遍曆[1, 2, 3] v += 100 //v是複製對象中的值,不會改變a數組元素的值 } fmt.Println(a) //1 2 3 }
|
樣本二:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
package main import "fmt" func main(){ a := [3]int {1, 2, 3} for i, v := range a{ //i,v從a複製的對象裡提取出 if i == 0{ a[1], a[2] = 200, 300 fmt.Println(a) //輸出[1 200 300] } a[i] = v + 100 //v是複製對象裡的元素[1, 2, 3] } fmt.Println(a) //輸出[101, 102, 103] }
|
2. 使用range迭代遍曆參考型別時,底層的資料不會被複製:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
package main import "fmt" func main(){ a := []int {1, 2, 3} //改成slice for i, v := range a{ if i == 0{ a[1], a[2] = 200, 300 fmt.Println(a) //[1 200 300] } a[i] = v + 100 } fmt.Println(a) }
|
結果:
1 2
|
[1 200 300] [101 300 400]
|
因為切片的內部結構為struct slice{*point, len, cap}。
資料部分是一個指標,指向地址,複製對象的時候只是把指標的值複製了,而不是重新拷貝一塊新的記憶體再把值放進去,所以修改的時候還是修改的原來的值,和C++裡的淺拷貝一樣。