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

这篇具有很好参考价值的文章主要介绍了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 文章来源地址https://www.toymoban.com/news/detail-822206.html

到了这里,关于go中for range的坑以及解决方案的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • signature hdr data: BAD, no. of btyes(9088) out of range 问题排查与解决方案

    在使用yum工具安装gcc的时候,报出了 signature hdr data: BAD, no. of btyes(9088) out of range 的问题 这是由于centos8中rpm工具存在的一个bug,在校验安装包头部大小的时候,应当限制为64M,但是实际限制了64k 这个问题存在于 rpm-4.14.3-4.el8.x86_64 等版本 查看你本机的rpm版本可以使用命令 解决

    2024年03月09日
    浏览(61)
  • Go for Range遍历

     遍历slice的时候会先获取slice的长度作为循环次数,在遍历过程中添加的元素不会被遍历到,map插入数据的位置是随机的,所以遍历过程中新插入的数据不能保证遍历到。 在forrange的过程中,数据会进行一次拷贝,我们如果直接对拷贝的数据进行操作是无法改变原来的数据的

    2024年02月13日
    浏览(37)
  • Golang中for和for range语句的使用技巧、对比及常见的避坑

    2024.1.0更新: Go 团队将修改 for 循环变量的语义,Go1.21 新版本即可体验! 今天看见了这篇文章,Go的1.22版本将更新,大致理解未会默认进行 v:=v 这个操作,因此此文所概述的许多坑,在1.22之后都可能会更新。 2024.2就会发布新版本,到时候再测试一下看看情况。 基础语法不

    2024年02月01日
    浏览(60)
  • 在CSDN学Golang场景化解决方案(EFK分布式日志系统方案)

    在 Golang EFK 分布式日志系统方案中,ElasticSearch 是一个分布式搜索引擎和数据存储库,它可以用于存储和搜索大量的日志数据。以下是 ElasticSearch 分布式集群部署的步骤: 下载 ElasticSearch:从 ElasticSearch 官网上下载最新版本的 ElasticSearch。 解压缩并安装 ElasticSearch:将下载下来

    2024年02月14日
    浏览(44)
  • 在CSDN学Golang场景化解决方案(微服务架构设计)

    在Golang微服务架构设计中,聚合器(Aggregator)微服务设计模式是一种常见的应用程序体系结构模式。该模式旨在简化客户端与后端微服务之间的通信,并支持更高级别的操作,例如聚合多个后端服务的数据。以下是一个简单的示例: 首先定义一个聚合器微服务: 在main函数中

    2024年02月14日
    浏览(39)
  • Go异步任务解决方案 Asynq

    今天为大家介绍一个Go处理异步任务的解决方案:Asynq,是一个 Go 库,用于排队任务并与 worker 异步处理它们。它由Redis提供支持,旨在实现可扩展且易于上手。 Asynq 是一个 Go 库,用于对任务进行排队并与工作人员异步处理它们。 Asynq 工作原理的高级概述: 客户端将任务放入

    2024年01月17日
    浏览(41)
  • 【go】异步任务解决方案Asynq实战

    Asynq 是一个 Go 库,一个高效的分布式任务队列。 Asynq 工作原理: 客户端(生产者)将任务放入队列 服务器(消费者)从队列中拉出任务并为每个任务启动一个工作 goroutine 多个工作人员同时处理任务 git库:https://github.com/hibiken/asynq Asynq 使用 Redis 作为消息代理。client 和 se

    2024年02月10日
    浏览(41)
  • 在CSDN学Golang场景化解决方案(OAuth2.0授权登录)

    OAuth 2.0 是一种用于授权的开放标准,可以让用户授权第三方应用程序访问他们存储在另一个服务提供商上的资源,例如图片、文本等。下面是 OAuth 2.0 协议的流程: 第三方应用程序向认证服务器请求授权。 认证服务器验证用户身份并生成一个访问令牌。 第三方应用程序使用

    2024年02月15日
    浏览(37)
  • go中 for循环的坑

    在使用for循环修改结构体切片中的值时,发现并没有修改成功。 结果切片中dog的name并没有全部变为123,后来查资料才知道for循环中的dog其实是个变量,指向的并不是真正的dog。 打印其地址对比可以看出压根就不同。 若要修改切片中的dog的name,应该按照以下这么写,或者将

    2023年04月26日
    浏览(28)
  • JS for循环异步解决方案

    JavaScript中的for循环是一种同步操作,它将阻塞代码的执行,直到循环完成。但是,在处理异步操作时,使用同步for循环会导致问题。 为了解决这个问题,可以使用以下两种异步解决方案: 递归是一种有效的解决方案,它可以确保异步操作按照预期执行。以下是使用递归实现

    2024年02月13日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包