go语言闭包捕获的是变量的引用而不是变量的值

在 Go 语言中,闭包捕获的是变量的引用,而不是变量的值。这意味着闭包会引用循环变量或外部变量的实际内存位置,而不是在闭包创建时复制变量的值。这种行为有时会导致意外的结果,尤其是在循环中创建多个闭包时。
在这里插入图片描述

闭包捕获变量的引用

考虑以下示例代码:

package main

import (
	"fmt"
	"sync"
)

func main() {
	var wg sync.WaitGroup
	for i := 0; i < 5; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			fmt.Println(i)
		}()
	}
	wg.Wait()
}

在这个示例中,所有 goroutine 捕获的是同一个 i 变量的引用。当所有 goroutine 开始执行时,i 的值已经是 5(因为循环已经结束),所以所有 goroutine 都会打印 5

解决方法

为了避免这种问题,可以采取以下两种方法之一:

方法一:使用匿名函数参数

通过将循环变量作为参数传递给匿名函数,可以确保每个 goroutine 捕获的是不同的值。

package main

import (
	"fmt"
	"sync"
)

func main() {
	var wg sync.WaitGroup
	for i := 0; i < 5; i++ {
		wg.Add(1)
		go func(i int) { // 将 i 作为参数传递
			defer wg.Done()
			fmt.Println(i)
		}(i)
	}
	wg.Wait()
}

在这个示例中,每次循环迭代都会创建一个新的匿名函数,并将当前的 i 值作为参数传递给这个函数。每个 goroutine 捕获的是传递给匿名函数的 i 参数,而不是循环变量 i 本身。这样每个 goroutine 都会打印出不同的值。

方法二:使用局部变量

通过在每次循环迭代中创建一个新的局部变量,可以确保每个 goroutine 捕获的是不同的变量。

package main

import (
	"fmt"
	"sync"
)

func main() {
	var wg sync.WaitGroup
	for i := 0; i < 5; i++ {
		wg.Add(1)
		j := i // 创建一个新的局部变量
		go func() {
			defer wg.Done()
			fmt.Println(j)
		}()
	}
	wg.Wait()
}

在这个示例中,每次循环迭代都会创建一个新的局部变量 j,并将当前的 i 值赋给 j。每个 goroutine 捕获的是不同的 j 变量,而不是循环变量 i 本身。这样每个 goroutine 也会打印出不同的值。

总结

在 Go 语言中,闭包捕获的是变量的引用,而不是变量的值。这意味着闭包会引用变量的实际内存位置,而不是在闭包创建时复制变量的值。为了避免在循环中创建多个闭包时出现意外的结果,可以使用匿名函数参数或将循环变量赋值给一个新的局部变量,确保每个 goroutine 捕获的是不同的变量。这两种方法都可以有效解决这个问题,确保每个 goroutine 打印出预期的值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/920532.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

记录eslint报错的情况

这几天在调试vue的eslint&#xff0c;害&#xff0c;我领导说eslint要打开规范代码&#xff0c;顺带看了一下eslint的规则&#xff0c;并且研究一下报错。切记每次修改了.eslintrc配置文件&#xff0c;需要重启项目再查看控制台&#xff0c;否则之前的报错会一直存在。 第一个…

Flink错误:一historyserver无法启动,二存在的文件会报错没有那个文件或目录

一.historyserver无法启动 historyserver执行了启动命令后却没有启动&#xff0c;而且也没有报错&#xff0c;如果日志无法启动的话网页8082是无法访问的 只能去查看日志 去flink的log文件查看日志&#xff1a; 发现应该是缺包了&#xff0c;导入jar包后可以解决 &#xff1a…

QT实操中遇到的一些(C++)疑惑点汇总

QT实操中 遇到的一些C疑惑点汇总 1.实例化对象的两种方法及其访问方式 1.1 示例 1.2 总结 2.基类成员的访问 2.1 直接访问继承的基类成员 2.1.1示例代码 2.1.2 输出结果 2.2 使用作用域解析符来显式调用基类成员函数 2.2.1 示例代码 2.2.2 输出结果 2.3 使用 this 指针访问基类…

【运维自动化-作业平台】如何使用全局变量之数组类型?

数组类型的全局变量也是作业平台里常用的&#xff0c;支持关联数组和索引数组&#xff0c;目前仅支持shell&#xff0c;语法跟shell一致。索引数组 语法 arry(1 2 3 a b c) ---定义一个数组arry ${arry[*]} ---获取所有数组元素 ${arry[]} ---获取所有数组元素 ${arry[0]} --…

docker安装zabbix +grafana

安装zabbix grafana 1、部署 mkdir -p /opt/zabbix/{data,backups}mkdir -p /opt/grafanasudo chown -R 472:472 /opt/grafanasudo chmod -R 755 /opt/grafanacat > docker-compose.yml <<-EOF version: 3.3services:mysql-server:image: mysql:8.1container_name: m…

容器安全检测和渗透测试工具

《Java代码审计》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484219&idx1&sn73564e316a4c9794019f15dd6b3ba9f6&chksmc0e47a67f793f371e9f6a4fbc06e7929cb1480b7320fae34c32563307df3a28aca49d1a4addd&scene21#wechat_redirect Docker-bench-…

GB 35114-2017 学习笔记(规避版权阉割版)

GB 35114-2017 学习笔记&#xff08;规避版权阉割版&#xff09; openstd.samr.gov.cn 国家标准全文公开系统 这个政府网站提供GB 35114-2017标准的的预览和下载&#xff0c;有需要的自行下载 GB 35114-2017作为一个国家强制标准&#xff0c;在国家标准全文公开系统 自己做个…

高校企业数据挖掘平台推荐

TipDM数据挖掘建模平台是由广东泰迪智能科技股份有限公司自主研发打造的可视化、一站式、高性能的数据挖掘与人工智能建模服务平台&#xff0c;致力于为使用者打通从数据接入、数据预处理、模型开发训练、模型评估比较、模型应用部署到模型任务调度的全链路。平台内置丰富的机器…

ROSSERIAL与Arduino IDE交叉开发(UBUNTU环境,包含ESP32、arduino nano)

ROSSERIAL与Arduino IDE交叉开发 一、简介二、安装1、Ubuntu下的Arduino IDE安装 **针对ESP32报错问题原因溯源和修改**三、运行结点 一、简介 这个教程展示在ubuntu环境下如何利用Arduino IDE配合rosserial开发机器人部件。通过Arduino IDErosserial实现arduino/esp32开发板通…

word-毕业论文的每一章节的页眉单独设置为该章的题目怎么设置

在Microsoft Word中&#xff0c;为毕业论文的每个章节设置不同的页眉&#xff0c;通常需要使用“分节符”来分隔各个章节&#xff0c;然后在每个章节中单独设置页眉。以下是详细步骤&#xff1a; 使用分节符 插入分节符&#xff1a; 将光标放在每个章节的末尾&#xff08;注意…

Flutter:SlideTransition位移动画,Interval动画延迟

配置vsync&#xff0c;需要实现一下with SingleTickerProviderStateMixinclass _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin{// 定义 AnimationControllerlate AnimationController _controller;overridevoid initState() {super.…

H.265流媒体播放器EasyPlayer.js网页全终端安防视频流媒体播放器可以播放本地视频吗

H.264/H.265播放器EasyPlayer.js主要用于在网页上实现视频播放功能&#xff0c;特别是针对RTSP流的播放。它允许开发者在不需要安装额外插件或软件的情况下&#xff0c;直接在网页中嵌入和播放来自监控摄像头或其他RTSP源的视频流。 可以播放本地视频吗&#xff1f; 回答&…

Linux: 任务的定时与延期

概述 ls 这种命令是立刻执行的命令&#xff0c;在linux中命令还可以延时执行&#xff0c;它们都涉及到时间的观念 常用命令 先来看下有关系统时间的规格 1 &#xff09; date 命令调节时间 $ date 显示当前时间还可以去定制 date 的一个输出, $ man date 可自定义输出 $ d…

RBAC——基于角色的访问控制

目录 一、RBAC核心概念 1. 角色&#xff08;Role&#xff09; 2. 用户&#xff08;User&#xff09; 3. 权限&#xff08;Permission&#xff09; 4. 会话&#xff08;Session&#xff09; 二、RBAC模型的演进 1. RBAC0&#xff1a;基本模型 2. RBAC1&#xff1a;角色…

OceanBase V4.x应用实践:如何排查表被锁问题

DBA在日常工作中常常会面临以下两种常见情况&#xff1a; 业务人员会提出问题&#xff1a;“表被锁了&#xff0c;导致业务受阻&#xff0c;请帮忙解决。” 业务人员还会反馈&#xff1a;“某个程序通常几秒内就能执行完毕&#xff0c;但现在却运行了好几分钟&#xff0c;不清楚…

同三维T80003JEHS 4K/60帧HDMI/SDI超高清H.265解码器

1路HDMI和1路SDI输出&#xff0c;1路3.5音频输入和1路3.5音频输出&#xff0c;1个USB2.0口1个USB3.0口&#xff0c;带1个RS232串口&#xff0c;2个网口&#xff0c;支持1路4K60或4路4K30或16路1080P或32路720P解码输出。4种画面分割显示模式。 产品简介&#xff1a; 同三维T80…

【更新中】《硬件架构的艺术》笔记(五):低功耗设计

介绍 能量以热量形式消耗&#xff0c;温度升高芯片失效率也会增加&#xff0c;增加散热片或风扇会增加整体重量和成本&#xff0c;在SoC级别对功耗进行控制就可以减少甚至可能消除掉这些开支&#xff0c;产品也更小更便宜更可靠。本章描述了减少动态功耗和静态功耗的各种技术。…

网络安全审计概述与分类

目录 网络安全审计概述等保五个级别对审计要求网络安全审计系统组成网络安全审计系统类型 网络安全审计概述 4A分别是认证、授权、账号、审计 网络安全审计是指对网络信息系统的安全相关活动信息进行获取、记录、存储分析和利用的工作。 网络安全审计的作用在于建立“事后”…

安宝特方案 | AR助力紧急救援,科技守卫生命每一刻!

在生死时速的紧急救援战场上&#xff0c;每一秒都至关重要&#xff01;随着科技的发展&#xff0c;增强现实&#xff08;AR&#xff09;技术正在逐步渗透到医疗健康领域&#xff0c;改变着传统的医疗服务模式。 安宝特AR远程协助解决方案&#xff0c;凭借其先进的技术支持和创新…