Go:坑之for range
go只提供了一种循环方式,即for循环,在使用时可以像c那样使用,也可以通过for range方式遍历容器类型如数组、切片和映射。但是在使用for range时,如果使用不当,就会出现一些问题,导致程序运行行为不如预期。比如,下面的示例程序将遍历一个切片,并将切片的值当成映射的键和值存入,切片类型是一个int型,映射的类型是键为int型,值为*int,即值是一个地址。
package main
import "fmt"
func main() {
slice := []int{0, 1, 2, 3}
myMap := make(map[int]*int)
for index, value := range slice {
myMap[index] = &value
}
fmt.Println("=====new map=====")
prtMap(myMap)
}
func prtMap(myMap map[int]*int) {
for key, value := range myMap {
fmt.Printf("map[%v]=%v\n", key, *value)
}
}
运行程序输出如下:
=====new map=====
map[3]=3
map[0]=3
map[1]=3
map[2]=3
由输出可以知道,不是我们预期的输出,正确输出应该如下:
=====new map=====
map[0]=0
map[1]=1
map[2]=2
map[3]=3
但是由输出可以知道,映射的值都相同且都是3。其实可以猜测映射的值都是同一个地址,遍历到切片的最后一个元素3时,将3写入了该地址,所以导致映射所有值都相同。其实真实原因也是如此,因为for range创建了每个元素的副本,而不是直接返回每个元素的引用,如果使用该值变量的地址作为指向每个元素的指针,就会导致错误,在迭代时,返回的变量是一个迭代过程中根据切片依次赋值的新变量,所以值的地址总是相同的,导致结果不如预期。
修正后程序如下:
package main
import "fmt"
func main() {
slice := []int{0, 1, 2, 3}
myMap := make(map[int]*int)
for index, value := range slice {
num := value
myMap[index] = &num
}
fmt.Println("=====new map=====")
prtMap(myMap)
}
func prtMap(myMap map[int]*int) {
for key, value := range myMap {
fmt.Printf("map[%v]=%v\n", key, *value)
}
}
运行程序输出如下:
=====new map=====
map[2]=2
map[3]=3
map[0]=0
map[1]=1
Go:坑之for range的更多相关文章
- 学习-go语言坑之for range
引用自 http://studygolang.com/articles/9701 go只提供了一种循环方式,即for循环,在使用时可以像c那样使用,也可以通过for range方式遍历容器类型如数组. ...
- Golang中的坑二
Golang中的坑二 for ...range 最近两周用Golang做项目,编写web服务,两周时间写了大概五千行代码(业务代码加单元测试用例代码).用Go的感觉很爽,编码效率高,运行效率也不错,用 ...
- Python04 range()方法的使用、turtle.textinput()方法和write()的使用、turtle.numinput()的使用
1 range() 方法的使用 1.1 range方法介绍 range方法会返回一个range类型的对象,该对象会根据range方法的参数产生一些列整型数据 技巧01:range方法有三个参数,第一个 ...
- go语言---for range
学习-go语言坑之for range https://www.cnblogs.com/hetonghai/p/6718250.html go只提供了一种循环方式,即for循环,在使用时可以像c那样使用 ...
- test_action
[TOP] 为什么百度校招数据挖掘工程师的笔试题目是跟数据挖掘关系不大? - 研究生生活交流 - 王道论坛,专注于计算机考研的点点滴滴! http://www.cskaoyan.com/thread- ...
- go相关资料
1.go的调度2.go struct能不能比较 因为是强类型语言,所以不同类型的结构不能作比较,但是同一类型的实例值是可以比较的,实例不可以比较,因为是指针类型 3.go defer(for defe ...
- IDEA_MyBatis_SQLException:Parameter index out of range坑
报错信息:超出数据库数据表设定的规定长度了 nested exception is org.apache.ibatis.type.TypeException: Could not set parame ...
- Golang -- range小坑铭记
废话少叙,先上一段代码,猜猜预期的效果. package main import ( "fmt" ) type student struct { Name string Age i ...
- 深度挖掘,Html5的 Range 滑动刻度的坑,兼容全平台,将任性进行到底!
最近2天一直在弄一个滑动的刻度效果,由于项目是基于Web App开发的,于是考虑到 移动端和pc端 的兼容性问题,考虑的比较多,尝试采用 Html5的Range 来做,目前已经兼容 pc端和移动端! ...
随机推荐
- BZOJ 2058 [Usaco2010 Nov]Cow Photographs:逆序对【环上最小逆序对】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2058 题意: 给你一个由1~n组成的排列,首尾相接围成一个环. 你可以任意次交换其中两个相 ...
- 分享知识-快乐自己:FastDFS 图片服务器的搭建
使用一台虚拟机来模拟,只有一个Tracker.一个Storage服务,配置nginx访问图片. 1):安装依赖包 yum -y install zlib zlib-devel pcre pcre-de ...
- ES doc_values的来源,field data——就是doc->terms的正向索引啊,不过它是在查询阶段通过读取倒排索引loading segments放在内存而得到的?
Support in the Wild: My Biggest Elasticsearch Problem at Scale Java Heap Pressure Elasticsearch has ...
- Netty5.x中新增和值得注意的点(转载http://www.coderli.com/netty-5-new-and-noteworthy/)
该文档会列出在Netty新版本中值得注意变化和新特性列表.帮助你的应用更好的适应新的版本. 不像Netty3.x和4.x之间的变化,5.x没有那么大的变化,不过也取得了其简化设计中的一些突破性进展 ...
- iOS NET Error Code
see NSURLError.h Define NSURLErrorUnknown = -, NSURLErrorCancelled = -, NSURLErrorBadURL = -, NSURLE ...
- javascript之原型prototype
理解JavaScript原型 http://blog.jobbole.com/9648/ Web程序员应该知道的Javascript prototype原理 http://www.leonzhang. ...
- CF 914 G Sum the Fibonacci —— 子集卷积,FWT
题目:http://codeforces.com/contest/914/problem/G 其实就是把各种都用子集卷积和FWT卷起来算即可: 注意乘 Fibonacci 数组的位置: 子集卷积时不能 ...
- MYSQL主从复制配置遇到的问题
在进行配置从服务器时遇到的错误. mysql> change master to master_host='192.168.136.129',master_user='repl',master_ ...
- mongodb数据迁移的两种方式
环境说明:bbs数据采集的数据越来越多,目前是50G,每天大概以200W的数据量增长.而当前服务器1.2上面的空间不足,需要把数据迁移到空间足够大的1.3上面去 尝试了2种方式对数据进行迁移,一种是r ...
- puppet插件fact和hiera(puppet自动化系列3)
四.Fact插件 4.1 使用pluginsync进行发布 这种方法比较特殊,节点factpath目录里除了编写好的rb文件之外,还需要在puppet模块中引用,运行一次之后才会转换成fact.通常在 ...