首页 > 其他分享 >go 循环变量捕获 陷阱

go 循环变量捕获 陷阱

时间:2023-08-01 11:55:57浏览次数:33  
标签:task getBadgesTasks 函数 捕获 goroutine spaceId 循环 陷阱 go

以下这样的循环代码,最后会发现spaceId都是同一个!!!!

	for _, spaceId := range spaceIds {
		task := func() {
			uc.log.WithContext(ctx).Errorf("SpaceUsecase::GetSpaces uc.badgeClt.Get spaceId:%v start!!!!", spaceId)
		}
		getBadgesTasks = append(getBadgesTasks, task)
	}

这是因为在任务函数 task 中,spaceId 是一个外部变量,它在任务函数被创建时捕获了当前循环迭代的值。这种情况被称为“循环变量捕获”,是 Go 语言中的一个常见陷阱。

在循环中启动 goroutine 时,如果不采取特定的措施,那么所有 goroutine 都会共享同一个循环变量,最终会导致它们所有的 spaceId 都是相同的。在这个例子中,由于 task 函数被添加到 getBadgesTasks 切片中,因此每次调用 task 时,都会使用相同的 spaceId 值。

为了避免这个问题,可以将循环变量的值传递给任务函数作为参数,从而使每个 goroutine 都有自己的 spaceId 值。例如:

for _, spaceId := range spaceIds {
    task := func(spaceId int32) {
        // 在函数内使用 spaceId 参数
        // ...
    }
    getBadgesTasks = append(getBadgesTasks, func() { task(spaceId) })
}

在这种情况下,每个任务函数都会创建一个新的闭包,其中 spaceId 的值被捕获并传递给任务函数的参数,在每次迭代时都会创建一个新的闭包和参数。这样,每个 goroutine 都会有自己的 spaceId 值,可以避免相互影响的问题。

标签:task,getBadgesTasks,函数,捕获,goroutine,spaceId,循环,陷阱,go
From: https://www.cnblogs.com/zhanchenjin/p/17596078.html

相关文章

  • OpenHarmony系统解决方案 - 接入多个显示设备卡开机Logo
    问题描述问题环境系统版本:OpenHarmony-3.2-Release问题现象接入多个显示设备后,启动系统偶现卡开机Logo。异常效果:系统卡在开机Logo界面,长时间无法显示开机动画,并且无法进入系统。正常效果:系统启动成功,显示开机动画,开机动画结束后显示锁屏界面。问题原因在窗口子系统中Abstra......
  • could not import go.etcd.io/etcd/clientv3-go
    问题描述今天在封装etcd的时候导包报错:couldnotimportgo.etcd.io/etcd/clientv3(norequiredmoduleprovidespackage"go.etcd.io/etcd/clientv3")问题解决:get:确保下载了client包gogetgo.etcd.io/etcd/clienttidygomodtidy本文由mdnice多平台发布......
  • django 简单文件上传
    通过模型来处理上传的文件¶如果想要在 FileField 上的 Model 保存文件,使用 ModelForm 会让这一过程变得简单。当调用 form.save() 时,文件对象将会被保存在对相应 FileField 的 upload_to 参数所指定的地方:fromdjango.httpimportHttpResponseRedirectfromdja......
  • go操作kafka
    go操作kafkaZooKeeper是一个分布式协调服务,它的主要作用是为分布式系统提供一致性服务,提供的功能包括:配置维护、命名服务、分布式同步、组服务等。Kafka的运行依赖ZooKeeper。目前kafka3.2.0以上版本(kafka_2.13-3.2.0.tgz)内就包含自带的ZooKeeper,因此直接下载Kafka就行。解......
  • 【go语言】3.1.2 接口的定义和实现
    在Go中,接口是一种抽象类型,用来描述其他类型应该有哪些方法。它定义了一组方法,但没有实现。这些方法由其他类型实现。接口的定义接口定义的格式如下:typeInterfaceNameinterface{Method1(param1type1,param2type2)returntype1Method2(param1type1,param2ty......
  • MongoDB数据库的部署和应用
    推荐步骤:在Centos01上部署MongoDB服务器客户端登录验证在centos01的MongoDB配置文件通过配置文件控制MongoDB服务,配置MongoDB身份验证在centos01的MongoDB服务器配置身份验证管理和修改配置文件支持验证在centos01管理MongoDB管理数据,集合批量数据管理实验步骤创建管理MongoDB组和......
  • Django 动态操作model
    fromdjango.appsimportappsforoinoids_result:oid_result=snmp.snmpWalk(o.oid)ifo.model_filed_nameandlen(o.model_filed_name)>0:field_name=o.model_filed_name.get('field_......
  • 通过局域网访问连接 vite 或 Django 之类的项目
    博客地址:https://www.cnblogs.com/zylyehuo/step1将vite或Django类的项目启动ip设置为0.0.0.0:端口step2查询本机电脑在当前局域网下的ipstep3将跳转路径改为查询到的本机ip,再加上第一步中设置的前端端口......
  • Python基础day56 Django URL分组设置
    URL函数的使用(支持正则表达式)#django1中使用的是urlurl('test',views.test),url函数的第一个参数是支持正则表达式的如果匹配到一个路由,就不在往下匹配,直接执行路由对应的视图函数#http://127.0.0.1:8000/test/是django默认设置的,django会先拿着test去匹配,如果匹配不......
  • URL函数的使用(支持正则表达式)、分组、反向解析、Django2的转换器、路由分发、伪静态的
    url('test',views.test),url函数的第一个参数是支持正则表达式的如果匹配到一个路由,就不在往下匹配,直接执行路由对应的视图函数 http://127.0.0.1:8000/test/是django默认设置的,django会先拿着test去匹配,如果匹配不到,它会自动加一个斜杠再次去匹配 去浏览器器搜索textadd只......