最近在开发中使用了for range来遍历一个slice,结果在测试的时候遇到了bug,最后定位是错误使用for range造成的,这里记录一下:

func redisSlaveScanBigKeys(slaveClient *redis.Client, bigKeyChan chan *bigKeyInstance, wg *sync.WaitGroup) {
var cursor uint64 = 0
for {
page, cursor_new, error := slaveClient.Scan(cursor, "*", 10000).Result()
if error != nil {
fmt.Printf("scan keys error, client is %v, error is %s\n", slaveClient, error.Error())
}
cursor = cursor_new
pipeCount := 0
piper := slaveClient.Pipeline()
pageCount := len(page)
keySlice := make([]*string, 0, 10)
for _, key := range page {
pageCount--
pipeCount++
piper.Type(key)
     fmt.Println(key, ":", &key)
    keySlice = append(keySlice, &key) ........
}
if cursor_new == 0 {
wg.Done()
break
}
}
}

上面的代码在测试运行中发现,每一个keyslice中的内容都相同,后来在红色的地方发现每一次for .. range .. 循环中的key值都不同,但是 &key 地址是同一个地址。于是,就想了解一下 for .. range .. 的实现:

对slice for range的实现
// The loop we generate:
// for_temp := range
// len_temp := len(for_temp)
// for index_temp = 0; index_temp < len_temp; index_temp++ {
// value_temp = for_temp[index_temp]
// index = index_temp
// value = value_temp
// original body
// } 对 map for range的实现
// The loop we generate:
// var hiter map_iteration_struct
// for mapiterinit(type, range, &hiter); hiter.key != nil; mapiternext(&hiter) {
// index_temp = *hiter.key
// value_temp = *hiter.val
// index = index_temp
// value = value_temp
// original body
// }

可以看到,对于slice 而言,for idx, value := range slice{}  中value的值是对slice中对应元素的拷贝。针对map而言,for key, value := range map 中 key, value的值也是对对应元素拷贝,如果使用该值变量的地址作为指向每个元素的指针,就会导致错误,在迭代时,返回的变量是一个迭代过程中根据切片依次赋值的新变量,所以值的地址总是相同的,导致结果不如预期。

for .. range中的坑的更多相关文章

  1. Golang中的坑二

    Golang中的坑二 for ...range 最近两周用Golang做项目,编写web服务,两周时间写了大概五千行代码(业务代码加单元测试用例代码).用Go的感觉很爽,编码效率高,运行效率也不错,用 ...

  2. go语言中的坑

    package main; import ( "fmt" "time" "sync" ) //修改slice的坑 func add(s [] ...

  3. 决策树python建模中的坑 :ValueError: Expected 2D array, got 1D array instead:

    决策树python建模中的坑 代码 #coding=utf-8 from sklearn.feature_extraction import DictVectorizerimport csvfrom ...

  4. Golang 中的坑 一

    Golang 中的坑 短变量声明  Short variable declarations 考虑如下代码: package main import ( "errors" " ...

  5. Mysql系列八:Mycat和Sharding-jdbc的区别、Mycat分片join、Mycat分页中的坑、Mycat注解、Catlet使用

    一.Mycat和Sharding-jdbc的区别 1)mycat是一个中间件的第三方应用,sharding-jdbc是一个jar包 2)使用mycat时不需要改代码,而使用sharding-jdbc时 ...

  6. Windows API中的坑

    本文主页链接:Windows API中的坑 ExpandEnvironmentStrings 风险: 进程会继承其父进程的环境变量.在展开如%APPDATA%等文件夹时,有可能父进程对此环境变量进行过 ...

  7. vue中的坑 --- 锚点与查询字符串

    在vue中,由于是单页面SPA,所以需要使用锚点来定位,在vue的官方文档中提到过也可以不使用锚点的情况,就是在vue-router中使用history模式,这样,在url中就不会出现丑陋的#了,但是 ...

  8. Torch-RNN运行过程中的坑 [2](Lua的string sub函数,读取中文失败,乱码?)

    0.踩坑背景 仍然是torch-rnn/LanguageModel.lua文件中的一些问题,仍然是这个狗血的LM:encode_string函数: function LM:encode_string( ...

  9. Torch-RNN运行过程中的坑 [1](读取Lua非空table,size为0)

    0.踩坑背景 执行Torch-RNN的时候,在LanguageModel.lua中的encode_string函数中,对start_text的各个character进行id映射编码,实现功能类似“北京 ...

随机推荐

  1. http请求中的三种参数类型

    1.URL参数:实际就是querry string的方式,参数拼接在url之后以?隔开,参数之间以&连接. 优点:简单,页面跳转比较快. 缺点:1.基于浏览器对urk长度有限制,不能超过204 ...

  2. BUAA_C++算法板子积累_动态规划、图算法、计算几何、FFT

    Hello #include <iostream> #include <cstdio> #include <cctype> #include <cmath&g ...

  3. Vue实例(1)

    vue入门示例(一) herokang 2019-08-21 15:33:58  12696  收藏 44 分类专栏: 前端 文章标签: vue入门 版权 为了让广大后端人员更快的理解上手vue,我们 ...

  4. Myql 中的事务回滚机制概述 ?

    事务是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个 不可分割的工作单位,事务回滚是指将该事务已经完成的对数据库的更新操作撤 销.要同时修改数据库中两个不同表时,如果它们不是一个事务 ...

  5. osi七层模型&tcp/udp

    1.TCP/UDP协议 1.1 TCP协议 可靠,速度慢,全双工通信 建立连接三次握手,断开连接四次挥手 建立起链接之后,发送每条消息都有回执,为了保证数据的完整性,还有重传机制 数据传输:有收必有发 ...

  6. C语言之标识符(知识点3)

    条件:用户表示符仅由大小写英文字母,数字和下划线组成,且第一个字符不能是数字 注意: 不能和关键字或函数库相同名字 但关键字的大写就可以用了,因为关键字都是小写的,而C语言区分大小写 案例

  7. SpringCloudAlibaba 微服务讲解(四)Sentinel--服务容错(二)

    4.7 Sentinel 规则 4.7.1 流控规则 流量控制,其原理是监控应用流量的QPS(每秒查询率)或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的榴莲高峰冲垮,从而保障应用 ...

  8. i2c总线编码

    i2c总线编码 发送启动信号S 在同步时钟线SCL 为高电平时,数据线出现的由高到低的下降沿. 启动信号子程序STA 1 /************************************** ...

  9. poj_1852_Ants(复杂问题简单化)

    原题传送门 描述 一群蚂蚁走在长度为l cm的水平细杆上,以1cm/s的匀速.当一只行走的蚂蚁到达杆的一端,它就会掉下去.当两只蚂蚁相遇,它们会掉头像反方向走去.我们知道一只蚂蚁在杆上的初始位置,然而 ...

  10. Dockerize an ASP.NET Core application

    原文:Dockerize an ASP.NET Core application 介绍 本示例演示了如何对ASP.NET Core应用程序进行容器化. 为什么要构建ASP.NET Core? 开源 在 ...