学习-go语言坑之for range

引用自 http://studygolang.com/articles/9701

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

  

时间: 2024-08-24 23:48:37

学习-go语言坑之for range的相关文章

不要这样学习C语言,这是个坑!

对于大部分初学者,学习C语言的目的是希望做一名合格的程序员,开发出靠谱的软件来.但是学了C语言的基本语法后,发现只能开发"黑底白字"的DOS程序,完全没有漂亮的界面和生动的交互.于是学数据结构,学算法,越陷越深,越来越难,最后迷失了,不知道学C语言能做什么,认为学习编程很难. 其实,这是很多初学者都会踩到的一个坑!C语言本身是一门很简单的语言,提供的实用功能不多,大部分要借助操作系统和其他库来完成. 第一阶段:学习软件开发基础 1) 首先学习C语言的基础语法,也就是本教程的前十章,这些

[转载]学习C语言基本思路与参考书籍

http://zhuanlan.zhihu.com/linjr/19694823 计算机行业发展非常快,大学里的教育基本都跟不上实际的社会需求.如果你所在的学校还在指定大家使用谭浩强的教材,或使用VC6.0来教大家上机实验,那你不妨看看本文,这里有一些建议可以帮助你不会脱离社会太远. 考虑到这是一个过来人感觉很基础,但是对于初学者又觉得困难重重的问题,我想如果这篇文章要想写得不让你觉得专业名词扎堆,内容高深莫测,读完还是不知所云,那最好的办法也许是,我们通过沟通的方式把整个「C语言应该怎么学」的

C语言学习:通过 GDB如何学习C语言

对于那些具有高级编程语言诸如: Ruby.Scheme.Haskell 等背景的人来说,学习 C 语言是具有挑战性的.除了纠结于 C  语言中像手动内存管理和指针等底层特性外,你必须在没有 REPL ( Read-Eval-Print Loop ) 的条件下完成工作.一旦你已经习惯于在 REPL 环境下进行探索性的编程,必须进行"编写-编译-运行"这样循环实在有点令人生厌. 最近我发现其实可以用 GDB 来作为 C 语言的伪 REPL.我一直尝试使用 GDB 作为学习 C 语言的工具,

轻松学习C语言编程的秘诀:总结+灵感

目前在准备一套C语言的学习教程,所以我这里就以C语言编程的学习来讲.注意,讲的是"轻松学习",那种不注重方法,拼命玩命的方式也有其效果,但不是我提倡的.我讲究的是在方式方法对头.适合你.减轻你学习负担和心里压力的前提下,才适当的抓紧时间. 因此,探索一种很好的学习方法就是我所研究的主要内容. 众所周知,学习C语言并非易事,要学好它更是难上加难.这和你期末考试背会几个题目的答案考上满分没多大关系,也就是说你考试满分也说明不了你学好.学精通了C语言.那么怎么才算学精通C语言?闭着眼睛对自己

第一节 为什么学习C语言

一  c语言的发展 : 1.1C语言的发展过程 C语言是在 70 年代初问世的.一九七八年由美国电话电报公司(AT&T)贝尔实验室正式发表了C语言.目的 改写 UNIX操作系统. 后来由美国国家标准协会(American National Standards Institute)在此基础上制定了一个C 语言标准,于一九八三年发表.通常称之为ANSI C. 1.2C语言的特点 1 C语言简洁.紧凑,使用方便.灵活. 高级语言 : a+b 汇编语言 :ADD AX,BX 机器语言 : 0000 00

C++教程 零基础如何学习C语言!

学习一门技术不是所想的很简单的一回事,学习C语言同样也不是一件简单的事!学好C语言,你想在短时间内学好,肯定是不可能的,但是也不需要你花个十年八年才嫩恶搞精通.今天小编就针对0基础的学员推荐给你们基本书籍以及技巧! 一.要读就读好书,否则不如不读 所有初学者面临的第一个问题便是:如何选择教材.好的开始是成功的一半,选择一本优秀的教材是事半功倍的关键因素.不幸的是,学校通常会帮你指定一本很差劲的C语言课本;而幸运的是,你还可以再次选择. 大名鼎鼎的谭浩强教授出了一本<C语言程序设计>,据说发行量

对大一新生开始学习C语言课程谈几点看法

大家好,首先祝贺大家进入了大学,迈入了大学的校门,也意味着开始了新的征程,希望大家能够有一个美好的大学四年. 先做下自我介绍,我叫李帅阳,(大家可以称呼我 李老师,或是班助,或是...)这是在邹欣老师的倡导下来担任你们学习C语言的助教,本学期将会与李光杰老师合作,非常荣幸能与各位一起度过这美好的一学期. 在本学期,我会竭尽全力为大家服务,希望能够帮助大家在C语言上获得更大的收获,并且能够在编程上找到乐趣. 对于C语言,想必各位都没有听过,但这是你们非常重要的课程,对于咱们专业,如果这门课程学得一

python学习遇到的坑

1. 定义变量名和函数名或关键字重名: typeerror 在网上随便copy了一个处理csv文件的源码,运行中总是在input时出错,差错没注意变量声明,导致浪费不少时间 在红色剪头处,input的输出用input变量名存放,当再次调用input函数时,就会提示:TypeError: str object is no callable 2. python输入csv文件内容有多余空行 Python中的csv的writer,打开文件的时候,要通过binary模式去打开,即带b的,比如wb,ab+等

在安卓手机上学习C语言 -- 前言

现在有很多学习C语言的系列教程, 不过这些教程都是在电脑上进行练习的, 这系列文章是给那些手上还没有电脑, 但对于编程有很大的兴趣的朋友看的. 这一系列的文章是写给没有编程基础的朋友的, 在这系列文章的前期, 可能会有一些类似于童话的谎言, 因为没有基础的朋友对于一些非常专业的术语可能会非常迷茫,而想要解释清楚这些术语需要非常多的陌生的概念.而这些概念可能比一个术语更加复杂, 所以在前期, 我会对一些非必要的术语进行片面的阐述. 这系列的文章我也是一时想起, 并没有建立好完善的体系 , 不过我会