golang mistakes-2

golang常见问题分享——奇怪的指针

定期更新总结使用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)
	}
}

输出:

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 < 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多平台发布

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值