for循环在我们日常编码中可能用的很多。在很多业务场景中我们都需要用for循环处理。但golang中的for循环有一个大大大的坑,大家可否遇到。直接上代码:
我们写一个测试类,定义一个切片数组,然后循环迭代每个元素,将元素的值放到另一个切片。循环finalArrays的时候按照我们的预期应该输出1、2、3、4。但事与愿违,输出的结果如下图:
懵逼了吧!为什么会出现这种奇怪的现象呢?这就是golang的循环变量的作用域导致的。
在golang的for循环中,循环内部创建的函数变量都是共享同一块内存地址,for循环总是使用同一块内存去接收循环中的的value变量的值。不管循环多少次,value的内存地址都是相同的。事实确实如此,我们输出value的内存地址看下:
所以,可以看到,整个4次循环过程中,所有变量值都是在0xc0000b8780这个内存地址上进行迭代的。4次循环都指向的是同一块内存地址,最后一次赋值的操作变量的值是4,指向了这块内存地址,所以前三次的值都变成了4。那我们怎么优化呢?我们只需要定义临时变量。
我们定义一个临时变量tmp,将value的值赋给tmp,问题就解决了。
总结:
①、for range循环遍历slice或map,值是复制的,且每次循环都是用同一个值保存复制后的值!
第一次循环时用value保存了第一个值,然后第二次循环时依然用value保存的第二个值,这就导致&value一直是一样的
②、产生这种问题的根本原因在于 for-range会使用同一块内存去接收循环中的值!
③、在 for _, value := range arrays 遍历中, _ 和 value 在内存中只会存在一份,即 之后每次循环时遍历到的数据都是以值覆盖的方式赋给 _ 和 value,_,value 的内存地址始终不变。
参考资料:
https://blog.csdn.net/weixin_39728544/article/details/110663483
https://studygolang.com/articles/9701
https://blog.csdn.net/weixin_39834090/article/details/110641807
声明:禁止任何非法用途使用,凡因违规使用而引起的任何法律纠纷,本站概不负责。
精彩评论