当前位置: 首页 > news >正文

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

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

闭包捕获变量的引用

考虑以下示例代码:

package mainimport ("fmt""sync"
)func main() {var wg sync.WaitGroupfor 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 mainimport ("fmt""sync"
)func main() {var wg sync.WaitGroupfor 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 mainimport ("fmt""sync"
)func main() {var wg sync.WaitGroupfor 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 打印出预期的值。

相关文章:

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

在 Go 语言中&#xff0c;闭包捕获的是变量的引用&#xff0c;而不是变量的值。这意味着闭包会引用循环变量或外部变量的实际内存位置&#xff0c;而不是在闭包创建时复制变量的值。这种行为有时会导致意外的结果&#xff0c;尤其是在循环中创建多个闭包时。 闭包捕获变量的引…...

周期法频率计的设计

目录 周期法频率计 分析&#xff1a; 设计过程&#xff1a; 周期法频率计 对于低频信号&#xff0c;应用周期法进行测频。周期法测频的基本原理是&#xff1a;应用标准频率信号统计被测信号两个相邻脉冲之间的脉冲数&#xff0c;然后通过脉冲数计算出被测信号的周期&#xff…...

【Linux】drop cache与reclaim的区别

前言 在 Linux 内核中&#xff0c;drop cache和reclaim是两种不同的内存管理机制&#xff0c;它们的目的和实现方式有所不同。 Drop Cache 定义 drop cache 是一种手动操作&#xff0c;允许用户通过向 /proc/sys/vm/drop_caches 写入特定的值&#xff0c;直接清除系统中的缓…...

【Linux课程学习】:命令行参数,环境变量

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;Linux课程学习 &#x1f337;追光的人&#xff0c;终会万丈光芒 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 命令行参数&#xff1a; 用命令行参数实现不同…...

HTB:WifineticTwo[WriteUP]

目录 连接至HTB服务器并启动靶机 信息搜集 使用rustscan对靶机TCP端口进行开放扫描 使用nmap对靶机开放端口进行脚本、服务扫描 使用curl访问靶机8080端口 使用浏览器直接访问/login路径 漏洞利用 使用searchsploit搜索该WebAPP漏洞 Payload USER_FLAG&#xff1a;bb…...

mac安装Pytest、Allure、brew

安装环境 安装pytest 命令 pip3 install pytest 安装allure 命令&#xff1a;brew install allure 好吧 那我们在安装allure之前 我们先安装brew 安装brew 去了官网复制了命令 还是无法下载 如果你们也和我一样可以用这个方法哦 使用国内的代码仓库来执行brew的安装脚本…...

关于相机选型的一些参数说明

上一篇&#xff1a;关于相机的一些参数计算&#xff08;靶面、视野等&#xff09; 目录 1.卷帘快门和全局快门1.1 卷帘快门1.2 全局快门PS&#xff1a;视觉伺服与快门选择 2.黑白和彩色3.CCD和CMOS3.1 CCD3.2 CMOSCCD VS CMOS 4.面阵和线扫4.1 面阵4.2 线扫4.3 面阵 VS 线扫 5.…...

深入解析 Cron 表达式高级用法:Spring 与 Linux Crontab 的全面对比与实践20241120

深入解析 Cron 表达式高级用法&#xff1a;Spring 与 Linux Crontab 的全面对比与实践 任务调度是后台服务中的重要组成部分&#xff0c;无论是定期数据备份、日志归档还是周期性报表生成&#xff0c;Cron 表达式始终是描述这些任务规则的核心工具。本文将聚焦 Spring Cron 表…...

24软专 数据结构

1、A[n]&#xff0c;k&#xff0c;将数组向右循环移动k位。要求时间复杂度O(n)&#xff0c;空间O(1)。 思路&#xff1a;采用三次反转数组的操作&#xff0c;可以实现时间复杂度为O(n)&#xff0c;空间复杂度为O(1)的算法。 void moveElem(int array[],int k,int length){//a…...

洛谷 P1616 疯狂的采药 C语言 记忆化搜索

题目&#xff1a; https://www.luogu.com.cn/problem/P1616?contestId215526 完全背包问题&#xff0c;最后一个超出空间了。完全背包和就是无限次的拿&#xff0c;公式跟01背包差不多。 但是&#xff0c;只有当前能拿和拿不下&#xff0c;换下一个。注意要处理好边界条件。…...

#渗透测试#红蓝攻防#HW#SRC漏洞挖掘01之静态页面渗透

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…...

element-plus入门教程:Button

一、Button组件概述 Element Plus的Button组件是一个常用的操作按钮&#xff0c;提供了多种类型、尺寸、状态等配置选项&#xff0c;以满足不同的交互需求。 二、安装Element Plus 在Vue 3项目中&#xff0c;可以通过npm或yarn来安装Element Plus。 npm install element-pl…...

oneplus6线刷、trwp、magisk(apatch)、LSPosed、Shamiko、Hide My Applist

oneplus6线刷android10.0.1 oneplus6线刷包(官方android10.0.1)下载、线刷教程&#xff1a; OnePlus6-brick-enchilada_22_K_52_210716_repack-HOS-10_0_11-zip 启用开发者模式 设置 / 连续点击6次版本号 : 启用开发者模式设置/开发者模式/{打开 usb调试, 打开 网络adb调试,…...

flux的版本

1.flux1-dev.safetensors https://huggingface.co/black-forest-labs/FLUX.1-devhttps://huggingface.co/black-forest-labs/FLUX.1-dev原生的23.8G的模型。原生12B的模型,float16的。需要配合ae.safetensors,flux1-dev.safetensors以及clip-l和T5的权重使用,注意ae.sft和f…...

Kafka 数据倾斜:原因、影响与解决方案

Kafka&#xff1a;分布式消息系统的核心原理与安装部署-CSDN博客 自定义 Kafka 脚本 kf-use.sh 的解析与功能与应用示例-CSDN博客 Kafka 生产者全面解析&#xff1a;从基础原理到高级实践-CSDN博客 Kafka 生产者优化与数据处理经验-CSDN博客 Kafka 工作流程解析&#xff1a…...

【从零开始的LeetCode-算法】3297. 统计重新排列后包含另一个字符串的子字符串数目 I

给你两个字符串 word1 和 word2 。 如果一个字符串 x 重新排列后&#xff0c;word2 是重排字符串的 前缀&#xff0c;那么我们称字符串 x 是 合法的 。 请你返回 word1 中 合法 子字符串的数目。 示例 1&#xff1a; 输入&#xff1a;word1 "bcca", word2 "…...

【2024APMCM亚太赛A题】完整参考论文与代码分享

A题 一、问题重述二、问题分析问题一&#xff1a;水下图像分类问题二&#xff1a;退化原因建模问题三&#xff1a;针对单一退化的图像增强方法问题四&#xff1a;复杂场景的综合增强模型问题五&#xff1a;针对性增强与综合增强的比较 三、问题假设退化特征独立性假设物理模型普…...

Excel求和如何过滤错误值

一、问题的提出 平时&#xff0c;我们在使用Excel时&#xff0c;最常用的功能就是求和了&#xff0c;一说到求和你可能想到用sum函数&#xff0c;但是如果sum的求和区域有#value #Div等错误值怎么办&#xff1f;如下图&#xff0c;记算C列中工资的总和。 直接用肯定会报错&…...

Android 常用命令和工具解析之GPU相关

目录 1、GPU基本信息 1.1 获取GPU基本信息 1.2 伪造GPU基本信息 2、GPU内存信息 3、经典案例 案例1&#xff1a;GPU伪造信息方案 案例2&#xff1a;GPU内存统计算法 GPU 指的是 Graphics Processing Unit&#xff0c;即图形处理单元。GPU 是一种专门用于处理图形和图像相…...

刷题——【模板】二维前缀和

前缀和 题目题目链接题解方法一方法二 题目 描述 给你一个 n 行 m 列的矩阵 A &#xff0c;下标从1开始。 接下来有 q 次查询&#xff0c;每次查询输入 4 个参数 x1 , y1 , x2 , y2 请输出以 (x1, y1) 为左上角 , (x2,y2) 为右下角的子矩阵的和&#xff0c; 输入描述&#x…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...