学习-go语言坑之for range
2017-04-16 11:21
1016 查看
引用自 http://studygolang.com/articles/9701
go只提供了一种循环方式,即for循环,在使用时可以像c那样使用,也可以通过for range方式遍历容器类型如数组、切片和映射。但是在使用for range时,如果使用不当,就会出现一些问题,导致程序运行行为不如预期。比如,下面的示例程序将遍历一个切片,并将切片的值当成映射的键和值存入,切片类型是一个int型,映射的类型是键为int型,值为*int,即值是一个地址。
运行程序输出如下:
由输出可以知道,不是我们预期的输出,正确输出应该如下:
但是由输出可以知道,映射的值都相同且都是3。其实可以猜测映射的值都是同一个地址,遍历到切片的最后一个元素3时,将3写入了该地址,所以导致映射所有值都相同。其实真实原因也是如此,因为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
- go语言坑之for range
- Go语言技巧:使用for range time.Tick()固定间隔时间执行
- Go语言学习笔记 --- 控制语句之if判断,循环语句for, switch语句和跳转语句
- go学习(十)——Go 语言范围(Range)
- Go语言学习笔记十二: 范围(Range)
- 学习go语言编程中 revel 框架的一个好例子
- go语言学习-golang的基本数据类型
- go语言学习-golang保留字
- go语言学习记录7
- go语言学习:web服务器 golang版
- go语言学习:web服务器 golang版
- Go语言学习札记——第三章 Go基本的程序设计结构(1)
- go语言学习记录3
- go语言学习记录4
- go 语言学习记录1
- go语言学习-在ubuntu上安装golang
- go语言学习笔记之slice用法
- go 语言学习 – 包的用法