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的更多相关文章

  1. 学习-go语言坑之for range

    引用自 http://studygolang.com/articles/9701 go只提供了一种循环方式,即for循环,在使用时可以像c那样使用,也可以通过for range方式遍历容器类型如数组. ...

  2. Golang中的坑二

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

  3. Python04 range()方法的使用、turtle.textinput()方法和write()的使用、turtle.numinput()的使用

    1 range() 方法的使用 1.1 range方法介绍 range方法会返回一个range类型的对象,该对象会根据range方法的参数产生一些列整型数据 技巧01:range方法有三个参数,第一个 ...

  4. go语言---for range

    学习-go语言坑之for range https://www.cnblogs.com/hetonghai/p/6718250.html go只提供了一种循环方式,即for循环,在使用时可以像c那样使用 ...

  5. test_action

    [TOP] 为什么百度校招数据挖掘工程师的笔试题目是跟数据挖掘关系不大? - 研究生生活交流 - 王道论坛,专注于计算机考研的点点滴滴! http://www.cskaoyan.com/thread- ...

  6. go相关资料

    1.go的调度2.go struct能不能比较 因为是强类型语言,所以不同类型的结构不能作比较,但是同一类型的实例值是可以比较的,实例不可以比较,因为是指针类型 3.go defer(for defe ...

  7. IDEA_MyBatis_SQLException:Parameter index out of range坑

    报错信息:超出数据库数据表设定的规定长度了 nested exception is org.apache.ibatis.type.TypeException: Could not set parame ...

  8. Golang -- range小坑铭记

    废话少叙,先上一段代码,猜猜预期的效果. package main import ( "fmt" ) type student struct { Name string Age i ...

  9. 深度挖掘,Html5的 Range 滑动刻度的坑,兼容全平台,将任性进行到底!

    最近2天一直在弄一个滑动的刻度效果,由于项目是基于Web App开发的,于是考虑到 移动端和pc端 的兼容性问题,考虑的比较多,尝试采用 Html5的Range 来做,目前已经兼容 pc端和移动端! ...

随机推荐

  1. Echarts一个页面加载多个图表及图表自适应

    Echarts一个页面加载多个图表及图表自适应 模块化加载 //入口 require.config({ paths: { echarts: 'http://echarts.baidu.com/buil ...

  2. python 正则表达式(二)

    下面列举了Python3的所有符号用法,别背,千万别背,用到时来查就行. 字符 含义 . 表示匹配除了换行符外的任何字符注:通过设置 re.DOTALL 标志可以使 . 匹配任何字符(包含换行符) | ...

  3. ES _source字段介绍——json文档,去掉的话无法更新部分文档,最重要的是无法reindex

    摘自:https://es.xiaoleilu.com/070_Index_Mgmt/31_Metadata_source.html The _source field stores the JSON ...

  4. 关于c++中char*、char ch[]和string区别

    一.字符串指针: char* ch="hello"; 这里的"hello"是字符串常量,是不可以改变的,即通过ch[0]="s"会编译出错. ...

  5. 3_observer

    #Observer 成就系统 achievements system 玩家完成某种成就后,通知监督者,监督者做出相应出来 ``` //简单来说就是事件触发的时候, 通知监督者 class Observ ...

  6. codeforces 652A A. Gabriel and Caterpillar(水题)

    题目链接: A. Gabriel and Caterpillar time limit per test 1 second memory limit per test 256 megabytes in ...

  7. Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]

    使用hibernate的时候,报出这个错误Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvir ...

  8. redis的缓存穿透 缓存并发 缓存失效

    我们在用缓存的时候,不管是Redis或者Memcached,基本上会通用遇到以下三个问题: 缓存穿透 缓存并发 缓存失效 一.缓存穿透 Paste_Image.png Paste_Image.png ...

  9. iOS项目添加PCH文件

    1.单击Info.plist右键单击->New File->Other->PCH File创建PCH文件 文件名设置成:项目名-Prefix  ->点击Create,创建成功. ...

  10. samba server导出/datasmb/目录;samba client挂载/data/至本地的/mydata目录;本地的mysqld或mariadb服务的数据目录设置为/mydata, 要求服务能正常启动,且可正常 存储数据;

    实验环境:CentOS7 主机(mini2) :172.16.250.247  主机名::localhost 客户端(mini3):172.16.253.99  主机名:pxe99 #主机:配置文件的 ...