内容简介:在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 指针、零指针、野指针
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Twenty Lectures on Algorithmic Game Theory
Tim Roughgarden / Cambridge University Press / 2016-8-31 / USD 34.99
Computer science and economics have engaged in a lively interaction over the past fifteen years, resulting in the new field of algorithmic game theory. Many problems that are central to modern compute......一起来看看 《Twenty Lectures on Algorithmic Game Theory》 这本书的介绍吧!