背景:
在一次代码测试过程中,发现了一个问题,该问题是这样的:
在我程序代码中有这么一段代码:(原代码和下面的代码类似)
# 其中一个goroutine从list中取出一个元素然后将其指针放入一个指定的channel中
list := []int{1,2,3,4,5,6,7}
ch := make(chan *int, 10)
for _, v := range list {
ch <- &v
}
# 然后另一个goroutine从channel中取出该元素并获取其值:
for v := range ch {
fmt.Println(*v)
}
大家猜猜第二个goroutine输出的结果是多少?
你肯定想不到,最后输出的结果竟然全是 7 !!!
当时因为这个问题,导致了很严重的测试bug,最后分析完发现,原来golang中的for k, v := range list 的方法,其value值在整个for循环中只定义了一个变量,其每一次循环只是简单的将值拷贝到该变量的地址处,所以,在for range中对value进行取地址操作没有任何意义!!!
那么这个问题我们应该怎样解决呢?
解决方法
很简单,我们不使用这个value值就好了,我们通过key值获取list中的变量即可进行地址传递:
如下:
# 其中一个goroutine从list中取出一个元素然后将其指针放入一个指定的channel中
list := []int{1,2,3,4,5,6,7}
ch := make(chan *int, 10)
for i := range list {
ch <- &(list[i])
}
# 然后另一个goroutine从channel中取出该元素并获取其值:
for v := range ch {
fmt.Println(*v)
}
如此一来,我们从channel中取出的元素就会是相应的 1,2,3,4,5,6,7 了。