使用Go语言经常会犯的错误。当我们遍历一个数组,如果用range
获取变量保存到另一个数组或者slice
时,会遇到令人困惑的问题。
func main() {
slice := []int{1, 2, 3}
var ptrSlice []*int
for _, v := range slice {
ptrSlice = append(ptrSlice, &v)
}
for _, v := range ptrSlice {
fmt.Println(*v)
}
}
输出:
3
3
3
原因分析
对于 for range
语句的实现,从编译器源码 gofrontend/go/statements.cc/For_range_statement::lower_range_slice()方法中可以看到有如下注释:
// The loop we generate:
// for_temp := range
// len_temp := len(for_temp)
// for index_temp = 0; index_temp < len_temp; index_temp++ {
// value_temp = for_temp[index_temp]
// index = index_temp
// value = value_temp
// original body
// }
用go
代码表示如下:
sa := s
sv1 := 0
sn := len(sa)
v1 := sv1
v2 := nil
for ; sv1