golang mistakes
定期更新总结应用golang过程中遇到的常见问题。
关注我,不迷路
2. 奇怪的指针
这个是应用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) }}
输入:
333
起因剖析
对于 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 := ssv1 := 0sn := len(sa)v1 := sv1v2 := nilfor ; sv1 < sn; sv1++ { tmp := sa[sv1] v1, v2 = sv1, tmp}
通过下面代码能够发现,返回的永远都是v2的变量,也就是获取的是v2变量的地址,所以输入的后果都是3
。
正确做法:
应用&slice[i]
代替&v
,代码如下:
func main() { slice := []int{1, 2, 3} var ptrSlice []*int for i, _ := range slice { ptrSlice = append(ptrSlice, &slice[i]) } for _, v := range ptrSlice { fmt.Println(*v) }}
本文由mdnice多平台公布