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. Linux课程---10、权限管理(权限有哪几种)

    Linux课程---10.权限管理(权限有哪几种) 一.总结 一句话总结: r 读 w 写 x 执行 1.drwxr-x---  2 root root  4096 Jan 20 19:39 mnt ...

  2. DBGrid1

    A.ShowMessage(IntToStr(Column.Index));   B.ShowMessage(IntToStr(dbgrid1.SelectedField.Index)); .得到当前 ...

  3. MVC中ajax调用Controller的方法

    1. ajax代码: $.ajax({ async: false, cache: false, type: 'POST', contentType: "application/json&qu ...

  4. linux系统配置之单一网卡配置多个不同网段IP(centos)

    1.用root权限的用户登录CENTOS,进入network-scripts文件夹下(本步骤可以省略,与二步骤一起完成): shell命令:cd /ect/sysconfig/network-scri ...

  5. Ubuntu 下安装mysql

    本文引用自 https://www.cnblogs.com/jpfss/p/7944622.html 此篇为http://www.cnblogs.com/EasonJim/p/7139275.html ...

  6. 【leetcode刷题笔记】Best Time to Buy and Sell Stock III

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

  7. Mybatis学习--XML映射配置文件

    学习笔记,选自Mybatis官方中文文档:http://www.mybatis.org/mybatis-3/zh/configuration.html MyBatis 的配置文件包含了影响 MyBat ...

  8. 每天一个linux命令(12):nl命令

    版权声明更新:2017-05-16博主:LuckyAlan联系:liuwenvip163@163.com声明:吃水不忘挖井人,转载请注明出处! 1 文章介绍 本文介绍了Linux下面的mv命令. 2. ...

  9. AtCoder Grand Contest 015 题解

    A - A+...+B Problem 常识 Problem Statement Snuke has N integers. Among them, the smallest is A, and th ...

  10. BZOJ4695:最假女选手

    浅谈区间最值操作和历史最值问题:https://www.cnblogs.com/AKMer/p/10225100.html 题目传送门:https://lydsy.com/JudgeOnline/pr ...