来源:自学PHP网 时间:2019-08-07 16:47 作者:小飞侠 阅读:次
[导读] 关于Golang中range指针数据的坑详解...
前言 在Golang中使用 for range 语句进行迭代非常的便捷,但在涉及到指针时就得小心一点了。 下面的代码中定义了一个元素类型为 *int 的通道 ch : package main import ( "fmt" ) func main() { ch := make(chan *int, 5) //sender input := []int{1,2,3,4,5} go func(){ for _, v := range input { ch <- &v } close(ch) }() //receiver for v := range ch { fmt.Println(*v) } } 在上面代码中,发送方将 input 数组发送给 ch 通道,接收方再从 ch 通道中接收数据,程序的预期输出应该是: 现在运行一下程序,得到的输出如下: 很明显,程序并没有达到预期的结果,那么问题出在哪里呢?我们将代码稍作修改: //receiver for v := range ch { fmt.Println(v) } 得到如下输出:
可以看到,5次输出变量 v ( *int )都指向了同一个地址,返回去检查一下发送部分代码: for _, v := range input { ch <- &v } 问题正是出在这里,在 for range 语句中, v 变量用于保存迭代 input 数组所得的值,但是 v 只被声明了一次,此后都是将迭代 input 出的值赋值给 v , v 变量的内存地址始终未变,这样再将 v 的地址发送给 ch 通道,发送的都是同一个地址,当然无法达到预期效果。 解决方案: 引入一个中间变量,每次迭代都重新声明一个变量 temp ,赋值后再将其地址发送给 ch : for _, v := range input { temp := v ch <- &temp } 抑或直接引用数据的内存(推荐,无需开辟新的内存空间): for k, _ := range input { c <- &input[k] } 再次运行,就可看到预期的效果。以上方案是用于讨论 range 语句带来的问题,当然,平时还是尽量避免使用指针类型的通道。 总结 以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对自学php网的支持。 |
自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习
京ICP备14009008号-1@版权所有www.zixuephp.com
网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com