go中for range的坑以及解决方案

一、for range的坑

相信小伙伴都遇到过以下的循环变量的问题,那是因为循环的val变量是重复使用的,即仅有一份。也就是说,每次循环后赋给val的值就会把前面循环赋给val的值替换掉,所以打印出来的值都是最后一次循环赋给val的值。

1、例子

func fr1() {
	arr := []int{1, 2, 3}
	for _, val := range arr {
		go func() {
            time.Sleep(time.Millisecond * 100)
			fmt.Println(val)
		}()
	}
	time.Sleep(time.Second)
}
//输出结果:3 3 3 


func fr2() {
	arr := [2]int{1, 2}
	arrnew := []*int{}
	for _, val := range arr {
		arrnew = append(arrnew, &v)
	}

	fmt.Println(*arrnew[0], *arrnew[1])
	//输出结果: 2 2
}

2、解决方案

使用局部变量/临时变量,即可解决

func fr1() {
	values := []int{1, 2, 3, 4, 5}
	for _, val := range values {
        //在这加入临时变量
		val := val 
		go func() {
			time.Sleep(time.Millisecond * 100)
			fmt.Println(val)
		}()
	}
	time.Sleep(time.Second)
}
//输出结果:2 3 1 4 5 或 5 3 4 1 2 等无序结果


//===========================或者=============================

func fr1() {
	values := []int{1, 2, 3, 4, 5}
	for _, val := range values {
        //传入变量
		go func(val int) {
			time.Sleep(time.Millisecond * 100)
			fmt.Println(val)
		}(val)
	}
	time.Sleep(time.Second)
}
//输出结果:2 3 1 4 5 或 5 3 4 1 2 等无序结果

二、官方解决方案

1、在Go1.21版本中,提前体验

        可以设置 GOEXPERIMENT=loopvar,就会解决以上问题,运行代码时就不会出现以上的坑。

Windows中设置举例

go env -w GOEXPERIMENT=loopvar
或
$env:GOEXPERIMENT="loopvar"
> go env
set GO111MODULE=on
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\Administrator\AppData\Local\go-build
set GOENV=C:\Users\Administrator\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=loopvar
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Users\Administrator\go\pkg\mod

2、预计在 Go1.22 起,在go.mod中支持

新的 for 循环语义,将会在 go.mod 文件中的 go 行(版本声明大于等于 Go1.22 下)默认应用也就不用设置 GOEXPERIMENT=loopvar 

相关推荐

  1. gofor range以及解决方案

    2024-01-11 23:58:02       59 阅读
  2. go 基础一些(2)

    2024-01-11 23:58:02       34 阅读
  3. go 基础一些

    2024-01-11 23:58:02       32 阅读
  4. 【开发掉go interface nil 判断

    2024-01-11 23:58:02       52 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-11 23:58:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-11 23:58:02       101 阅读
  3. 在Django里面运行非项目文件

    2024-01-11 23:58:02       82 阅读
  4. Python语言-面向对象

    2024-01-11 23:58:02       91 阅读

热门阅读

  1. 【源码阅读】交易池txs_list

    2024-01-11 23:58:02       39 阅读
  2. STL之map

    STL之map

    2024-01-11 23:58:02      44 阅读
  3. MySQL 8.0中新增的功能(十)

    2024-01-11 23:58:02       43 阅读
  4. 前端 PM(Project Manager) 分享

    2024-01-11 23:58:02       43 阅读
  5. 【Linux】linux踢出远程登录用户命令

    2024-01-11 23:58:02       54 阅读
  6. vue中实现锚点定位功能

    2024-01-11 23:58:02       63 阅读
  7. Vue的v-for指令、事件处理、表单控制

    2024-01-11 23:58:02       49 阅读
  8. 优化Vue首页加载速度的实用方法

    2024-01-11 23:58:02       59 阅读
  9. 【ASP.NET Core 基础知识】--MVC框架--Views和Razor语法

    2024-01-11 23:58:02       45 阅读
  10. Go 语言为什么不支持并发读写 map

    2024-01-11 23:58:02       51 阅读
  11. 前端web虚拟列表实现

    2024-01-11 23:58:02       66 阅读