内容简介:在Golang中使用下面的代码中定义了一个元素类型为在上面代码中,发送方将
在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) }
得到如下输出:
0x416020 0x416020 0x416020 0x416020 0x416020
可以看到,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
语句带来的问题,当然,平时还是尽量避免使用指针类型的通道。
以上所述就是小编给大家介绍的《Golang中range指针数据的坑》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 7. Go 语言数据类型:指针
- (一)C语言之基本数据类型、输入输出、指针
- bug诞生记——隐蔽的指针偏移计算导致的数据错乱
- 数据结构和算法面试题系列-C指针、数组和结构体
- Go 语言函数式编程系列教程(十三) —— 数据类型篇:指针的概念和基本使用
- NULL 指针、零指针、野指针
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
计算机程序设计艺术・卷3
[美] 高德纳(Donald E. Knuth) / 贾洪峰 / 人民邮电出版社 / 2017-2 / 198.00元
《计算机程序设计艺术》系列被公认为计算机科学领域的权威之作,深入阐述了程序设计理论,对计算机领域的发展有着极为深远的影响。本书为该系列的第3卷,全面讲述了排序和查找算法。书中扩展了卷1中数据结构的处理方法,并对各种算法的效率进行了大量的分析。一起来看看 《计算机程序设计艺术・卷3》 这本书的介绍吧!