在Golang中使用 for range 语句进行迭代非常的便捷,但在涉及到指针时就得小心一点了。

下面的代码中定义了一个元素类型为 *int 的通道 ch :

package mainimport ("fmt"
)func main() {ch := make(chan *int, 5)//senderinput := []int{1, 2, 3, 4, 5}go func() {for _, v := range input {ch <- &v}close(ch)}()//receiverfor 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 := vch <- &temp
}

抑或直接引用数据的内存(推荐,无需开辟新的内存空间):

for k, _ := range input {c <- &input[k]
}

再次运行,就可看到预期的效果。以上方案是用于讨论 range 语句带来的问题,当然,平时还是尽量避免使用指针类型的通道。

修改数据也是如此:

for k, _ := range input {input[k] = 1  // 直接对input赋值
}

golang range 遍历读写数据问题相关推荐

  1. golang range 遍历 索引和值

    在go语言中,遍历数据或切片时可以用range, range会产生两个值,分别是数据的索引与值, 错误的写法: package mainimport "fmt"func main( ...

  2. at24c16如何划分出多个读写区_如何1分钟遍历100T数据?

    如何快速遍历一个超大数据集 ? 文件是存储在磁盘上的,文件的读写访问速度受限于磁盘的物理限. 如果才能在1 分钟内完成 100T 大文件的遍历呢? 磁盘存储结构 磁盘是一种可持久保存,持续读写数据的存 ...

  3. Golang的for range遍历

    for range 可以遍历  切片.map等. for range 遍历时会首先计算切片的长度,然后创建每个元素的副本.而不是直接返回对该元素的引用,因此如果使用该值变量的地址作为指向每个元素的指针 ...

  4. golang之range遍历

    文章目录 range遍历 遍历slice 遍历map 遍历channel range是go提供的一种迭代遍历手段. range遍历 range遍历可操作的类型有数组(包括字符串).切片.Map.cha ...

  5. Golang如何遍历切片slice

    前言 这两天用golang开发一个把企业微信的打卡记录同步到HR-OA系统的一个中间表的功能,同步时把从企业微信接口里查询到的打卡记录放到一个对象的切片里,然后遍历切片把每条打卡记录写到中间表,这里涉 ...

  6. go语言初体验(流程控制、range遍历、函数、结构体、面向对象)

    一.流程控制 // main package mainimport ("fmt" )func main() {x := 2switch x {case 1:fmt.Print(&q ...

  7. Java18-day09【字节缓冲流、字符流、编码表、字符串与字符流中的编码解码问题、字符流读写数据的方式、字符缓冲流、IO流小结】

    视频+资料(工程源码.笔记)[链接:https://pan.baidu.com/s/1MdFNUADVSFf-lVw3SJRvtg   提取码:zjxs] Java基础--学习笔记(零起点打开java ...

  8. python list遍历删除_Python中list循环遍历删除数据的正确方法

    前言 初学Python,遇到过这样的问题,在遍历list的时候,删除符合条件的数据,可是总是报异常,代码如下: num_list = [1, 2, 3, 4, 5] print(num_list) f ...

  9. R语言观察日志(part5)--利用readr和readxl包读写数据

    学习笔记,仅供参考 利用readr和readxl包读写数据 读取数据 相关函数 函数包readr和readxl提供了一系列的数据读入功能,主要函数如下: #readr包read_delim(file, ...

最新文章

  1. java发送短信模板_java发送短信
  2. 雷达篇(六)电磁波的大气衰减
  3. Scala模式匹配(类似Java的switch)
  4. linux 8051 编译,[编译] 3、在Linux下搭建51单片机的开发烧写环境(makefile版)
  5. docker 不包含依赖 打包_Docker容器技术(概念篇)
  6. maven配置之:<distributionManagement>snapshot快照库和release发布库
  7. FusionCharts 的XML标签属性
  8. 马拉松教会我_社区教会了我关于开放组织的知识
  9. c++ msflexgrid 使用_丝杠支座组件C
  10. android wear 运动程序,Android Wear 之 为通知添加动作
  11. 如何下载谷歌地图高程数据
  12. 卡巴斯基7.0离线更新升级包病毒库
  13. python中merge函数_Python Merge函数原理及用法解析
  14. 对话OpenCV创始人Gary:“亚洲社会都太重视学历和证书”
  15. 淘淘商城第75讲——添加商品同步到索引库以及消息机制测试
  16. bcdedit添加linux引导,强大的BCDEdit工具-启动项等相关问题-设置默认开机启动项
  17. 腾讯QQ体验版 for Macv8.4.10.73官方
  18. Unity相机设置CullingMask
  19. 坚持一件事比决定一件事难多了
  20. 一文了解EpiQuik CUT&RUN m6A RNA富集(MeRIP)试剂盒

热门文章

  1. J-Flash的使用
  2. IDE接口驱动程序移植
  3. 当我们在讨论奢侈品行业时,人工智能可以做什么?
  4. mongochef如何链接有权限的mongodb3.x数据库
  5. Java的poi技术读取和导入Excel
  6. VMware 主机基板管理控制器的状态
  7. mysql有关权限的表都有哪几个
  8. 关于资产发现-嗅探法
  9. Kubuntu 9.10设置支持文件分级的方法
  10. D-Link防火墙操作初步