Go 語言中 range 關鍵字用于 for 循環(huán)中迭代,支持類型如下:
- 數組(array)
- 切片(slice)
- 通道(channel)
- 集合(map)
它返回元素的索引和索引對應的值,在集合中返回 key-value 對的 key 值。
使用起來非常方便
for index, value := range myArray {
fmt.Println("index: " + index)
fmt.Println("value: " + value)
}
這個簡單的使用方法里面,對新手來說,還是有坑的,而且非常不容易被發(fā)現。
package main
import "fmt"
type student struct {
Name string
Age int
}
func main() {
var stus []student
stus = []student{
{Name: "one", Age: 18},
{Name: "two", Age: 19},
}
data := make(map[int]*student)
// code1 這是不對的使用方法
for i, v := range stus {
data[i] = &v
}
for i, v := range data {
fmt.Printf("error: key=%d, value=%v \n", i, *v)
}
// code2 這是正確的使用方法
for i, _ := range stus {
data[i] = &stus[i]
}
for i, v := range data {
fmt.Printf("right: key=%d, value=%v \n", i, *v)
}
}
輸出結果是:
error: key=0, value={two 19}
error: key=1, value={two 19}
right: key=0, value={one 18}
right: key=1, value={two 19}
原因很明顯:
用for range來遍歷的時候,被遍歷的指針是不變的,每次遍歷僅執(zhí)行struct值的拷貝,即上面代碼中的變遍歷的 [v] 是對struct的值拷貝,因此 code1中 data[i] = &v 永遠取的值都是 v這個遍歷的地址。