博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
golang range循环内部
阅读量:5103 次
发布时间:2019-06-13

本文共 1441 字,大约阅读时间需要 4 分钟。

  • 一个疑惑和三个例子

下面的程序会无限执行下去吗?

func main() {	v := []int{1, 2, 3}	for i := range v {		v = append(v, i)	}}

思考一下下面三个例子的结果。

func IndexArray() {	a := [...]int{1, 2, 3, 4, 5, 6, 7, 8}	for i := range a {		a[3] = 100		if i == 3 {			fmt.Println("IndexArray", i, a[i])		}	}}func IndexValueArray() {	a := [...]int{1, 2, 3, 4, 5, 6, 7, 8}	for i, v := range a {		a[3] = 100		if i == 3 {			fmt.Println("IndexValueArray", i, v)		}	}}func IndexValueArrayPtr() {	a := [...]int{1, 2, 3, 4, 5, 6, 7, 8}	for i, v := range &a {		a[3] = 100		if i == 3 {			fmt.Println("IndexValueArrayPtr", i, v)		}	}}

 

  • range左值

可以  是 i := range 或者 i,v := range  ,变量已经被预先定义的话,这个 := 当然可以是 =  。

要注意的是 用 := 时,前面变量是被重用的,想当于第一次用的是 :=  后续循环用的是 =  。

 

  • range右值

可以是以下类型,或者返回以下类型的表达式

  1. array 或 array的指针
  2. slice
  3. string
  4. map
  5. 可从中接收的channel

表达式会在loop开始前计算。

如果只是i := range arr 或者 i := range *arr 这种只要数组索引的循环,由于数组是不可变的,因此在编译时候,可能直接计算len(arr),编译器直接用这个常量结果优化掉range。

 

  • 分析数据类型

再go中,每次分配都伴随copy,比如赋值,函数参数等。

以下几个类型的底层数据结构:

所以将一个数组分配给一个array,内存级别是整个array的一次复制。

string和slice的分配只是这两个类型头,或者叫做类型元信息结构体的复制,底层数组是没变化的。

map和channel也一样,只是指针的复制。

 

  • 编译器实现

range本质是for语句的一个语法糖。

编译器会在循环开始前copy一次循环对象。编译器的编译后的逻辑:

array:

slice:

可以看出数组是值类型会被整个复制一遍,大数组直接循环代价不小。应该使用数组指针来做循环对象,复制一个指针还是代价小的。

 

  • 关于map一个重要的信息

如果循环过程中,map的一个key-value没有被遍历到就被删除了,这个值在后续的遍历中不会出现。

遍历过程中一个key-value被创建了,继续遍历可能会遍历到这个key-value,也可能被跳过。这个应该涉及map底层的分桶实现。以后有机会介绍一下。

 

 

总之,把range理解成一个函数,被遍历的对象当作range的参数,这样理解或许更好。

 

以上实际是 理解半翻译 一篇博客:

 

转载于:https://www.cnblogs.com/adarking/p/8629191.html

你可能感兴趣的文章
linux--GCC用法
查看>>
Ubuntu下安装MySQL及简单操作
查看>>
OWIN是什么?
查看>>
前端监控
查看>>
centos6.5 mysql忘记登入密码
查看>>
Trusted Execution Technology (TXT) --- 启动控制策略(LCP)篇
查看>>
clipboard.js使用方法
查看>>
绘图库:Matplotlib
查看>>
0906第一次作业
查看>>
Ceph Monitor基础架构与模块详解
查看>>
dbca:Exception in thread "main" java.lang.UnsatisfiedLinkError: get
查看>>
hdu 1232 畅通工程(并查集)
查看>>
移动开发平台-应用之星app制作教程
查看>>
jquery validate使用笔记
查看>>
主要的几个脑网络——整理自eegfmri的博客
查看>>
leetcode 459. 重复的子字符串(Repeated Substring Pattern)
查看>>
CABasicAnimation animationWithKeyPath Types
查看>>
JavaScript--eval
查看>>
iOS6与iOS7屏幕适配技巧
查看>>
获取视图尺寸大小方法
查看>>