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

Golang中for和for range语句的使用技巧、对比及常见的避坑

前言

基础语法不再赘述,写这个原因是之前的某次面试被问道了,我知道会导致问题但具体答下来不是很通顺。再回想自己开发过程中,很多地方都是使用到了for/for range,但是却从没注意过一些细节,因此专门学习一下进行记录。

对一个数组循环,for range,使用kv时候有什么要注意的吗?
这个是当时面经记录的问题。因此顺着这里开始进行学习。

在这里插入图片描述

for和for range基本语法

for的用法大概可以类比C++里面的for和while

//类似C++的for 
for i := 0; i < 10; i++ {fmt.Println(i)
}
//类似C++的while
j := 0
for j < 10 {fmt.Println(j)j++
}//死循环
for {fmt.Println("无限循环")
}

fo range用法大概可以类比python的range。但是golang中他的用法更多,大致四种

//遍历数组:
numbers := [3]int{1, 2, 3}
for index, value := range numbers {fmt.Printf("索引:%d 值:%d\n", index, value)
}
//遍历切片:
names := []string{"Alice", "Bob", "Charlie"}
for index, name := range names {fmt.Printf("索引:%d 值:%s\n", index, name)
}
//遍历 map:
ages := map[string]int{"Alice": 25, "Bob": 30, "Charlie": 35}
for name, age := range ages {fmt.Printf("%s 的年龄是 %d 岁\n", name, age)
}
//遍历字符串:
sentence := "Hello, 世界"
for index, char := range sentence {fmt.Printf("索引:%d 字符:%c\n", index, char)
}

for和for range的区别

对于一个数组,例如a[3]={3.2.1},可以通过两种方式进行遍历:


func main() {fmt.Println("下面是for range遍历")var m = []int{1, 2, 3}for k, v := range m {fmt.Println(k, v)fmt.Println(&k, &v)}fmt.Println("下面是for遍历")for i := 0; i < 3; i++ {fmt.Println(i, m[i])fmt.Println(&i, &m[i])}
}

其结果如下:

在这里插入图片描述

我们可以发现,输出的结果是一样的,但地址却不一样:
因此这便是二者的本质区别——
1、range遍历在开始遍历数据之前,会先拷贝一份被遍历的数据。所以在遍历过程中去修改被遍历的数据,只是修改拷贝的数据,不会影响到原数据。
2、range在遍历值类型时,其中的v是一个局部变量,只会声明初始化一次,之后每次循环时重新赋值覆盖前面的。

常见的坑

通过指针取值

//此代码来自`https://zhuanlan.zhihu.com/p/105435646`
arr := [2]int{1, 2}
res := []*int{}
for _, v := range arr {res = append(res, &v)
}
//expect: 1 2
fmt.Println(*res[0],*res[1]) 
//but output: 2 2

这个是由于上述的区别2——v是一个只声明一次的局部变量。
修改方案两种:1、通过arr[k]获取值,而不是v。
2、使用一个局部变量:tmp :=v,之后对tmp处理。

循环中添加元素是否会导致死循环

func main() {s := []int{0, 1}for _, v := range s {s = append(s, v)}fmt.Printf("s=%v\n", s)
}

大致意思是这样会不会死循环?
这个是上面的性质1。range因为是对复制的数据在操作,所以不会影响。普通的for则会影响。

https://cloud.tencent.com/developer/article/1925475
此部分具体参考此例即可。

对大数据的操作

对于很大数据的数组,若采取range遍历,因为复制的缘故,所以会导致开销巨大。(具体见下的性能分析)
但是在大数据的数组下,使用range去重置(全部赋值为0),效率是高的。原因是内存是连续的,编译器会直接清空这一片的内存。具体讲解见此

demo和源码看这里的3和4

对于map的操作

具体来说,就是边遍历边新增/删除。删除了的不可能再遍历到,新增的可能再遍历到(不一定)。

原因:map内部实现是一个链式hash表,为了保证无顺序,初始化时会随机一个遍历开始的位置,所以新增的元素被遍历到就变的不确定了,同样删除也是一个道理,但是删除元素后边就不会出现,所以一定不会被遍历到。

具体参考此文的最后部分

range中开goroutine

func main() {var m = []int{1, 2, 3}for i := range m {go func() {fmt.Print(i)}()}time.Sleep(time.Millisecond)}

会发现输出结果有随机性:发现结果是222。原因是上述的那个,k、v是同一值,他并没有保存到goroutine的栈中。
解决方法还是局部变量,但可能出现012、210、102这样的值…原因是运行太快了,所以顺序不一定…

附1:range遍历的性能分析

for range需要进行一步复制操作,因此显然需要比for更多的性能开销。但是对于切片来说,因为切片的副本和原切片都是指向数组的地址,所以性能一样。
具体见此文。

https://blog.csdn.net/EDDYCJY/article/details/124701572

附2:一个坑中坑——map的range遍历并不是随机

具体参考此文

结论是:第一位的元素会有更高的概率被首先选中。因此不可用map遍历的随机性,作为随机选择map中元素的方法。

参考资源

Go 处理大数组:使用 for range 还是 for 循环?
Go的循环遍历使用小坑
Go 中for range的一个坑
Go语言中for-range使用踩坑指南
Dig101 - Go之for-range排坑指南
Golang 语言 for 和 for-range 的区别
5.1 for 和 range #

相关文章:

Golang中for和for range语句的使用技巧、对比及常见的避坑

前言 基础语法不再赘述&#xff0c;写这个原因是之前的某次面试被问道了&#xff0c;我知道会导致问题但具体答下来不是很通顺。再回想自己开发过程中&#xff0c;很多地方都是使用到了for/for range&#xff0c;但是却从没注意过一些细节&#xff0c;因此专门学习一下进行记录…...

Nestjs 微服务实战 - 动态微服务创建链接

所有的微服务都需要做服务治理 服务治理包括&#xff08;配置中心、服务发现、注册服务等等&#xff09;&#xff0c;常见的包括 Java 的 Nacos&#xff0c;这里不关注与服务治理&#xff0c;只说明&#xff0c;如何用 nest 网关&#xff0c;并且在网关层动态实现微服务注入 …...

K8S部署pod状态CreateContainerConfigError问题解决

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…...

PyTorch 简单易懂的实现 CosineSimilarity 和 PairwiseDistance - 距离度量的操作

目录 torch.nn子模块Distance Functions解析 nn.CosineSimilarity 功能 主要参数 输入和输出的形状 使用示例 nn.PairwiseDistance 功能 主要参数 输入和输出的形状 使用示例 总结 torch.nn子模块​​​​​​​Distance Functions解析 nn.CosineSimilarity torc…...

app加载不到aar中的so库

如何将so文件打入到aar包中 1 在main下面新建jniLibs目录并将so放进去 2 在android{}中添加 sourceSets {main {jniLibs.srcDir file(jni/)}}app引用不到aar中的so文件(巨坑&#xff0c;不去查谁知道啊) 在aar 的manifeset application标签中中添加 android:extractNativeLi…...

vue-springboot基于java的实验室安全考试系统

本系统为用户而设计制作实验室安全考试系统&#xff0c;旨在实现实验室安全考试智能化、现代化管理。本实验室安全考试管理自动化系统的开发和研制的最终目的是将实验室安全考试的运作模式从手工记录数据转变为网络信息查询管理&#xff0c;从而为现代管理人员的使用提供更多的…...

mysql+关掉密码过期

mysql关掉密码过期 要在MySQL中关闭密码过期功能&#xff0c;可以按照以下步骤进行操作&#xff1a; 登录到MySQL服务器。 使用管理员账户&#xff08;如root&#xff09;连接到数据库。 mysql -uroot -ppassword 运行以下命令来查看当前的密码过期设置&#xff1a; SHOW…...

实际项目中的环形缓冲区

在实际项目中&#xff0c;环形缓冲区的设计要比之前讲到的原型稍微复杂一些&#xff0c;需要一些接口函数来实现数据结构封装。GitHub上有个大帅哥写了一个轻量的环形缓冲区库&#xff0c;可以学习参考&#xff0c;也可以直接集成到自己的项目中&#xff0c;功能已经非常完善。…...

输出回文数-第11届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第23讲。 输出回文数&#…...

内存溢出会导致模块测试正常,植入系统失败

前些天&#xff0c;遇到了一个问题&#xff1a;需要在系统中添加一个小功能&#xff0c;单独测试&#xff0c;然后植入系统。 代码使用了从网上下载的函数&#xff0c;模块单独运行&#xff0c;没有问题&#xff0c;但是放在系统中运行就会出问题。 不得已的情况下&#xff0c…...

【taro react】 ---- QRCode 二维码生成

1. 需求分析 需要将输入的值转换为图片资源;由于只是单纯的展示,所以不需要很多比如加 logo 等复杂功能;不需要后端生成,直接前端操作;使用的第三方库尽可能小,功能单一;最后选择使用 qrcode-generator 库,只有 40kb。2. 使用第三方库 qrcode-generator 3. 转换 base…...

rk3566 armbian修复usb2.0并挂载U盘

文章目录 usb接口修复一 执行命令二 修改rk3566-panther-x2.dts⽂件三 查看是否识别 U盘格式化、挂载一 U盘格式化1.1 查看U盘1.2 查看U盘文件系统类型1.3 格式化为ext4系统 二 挂载U盘2.1 手动挂载2.2 自动挂载&#xff08;可选&#xff09; usb接口修复 一 执行命令 将位于…...

猫头虎博主第9期赠书活动:《YOLO目标检测》计算机AI视觉实战YOLO人工智能目标检测与跟踪图像处理深度学习图像检测书籍

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通Golang》…...

python 如何将英语单词翻译成中文

要将英语单词翻译成中文&#xff0c;可以使用 Python 的第三方库 googletrans。该库使用 Google Translate 提供的 API 来进行翻译。 首先&#xff0c;需要安装 googletrans 库。可以使用以下命令在终端或命令提示符中安装&#xff1a; pip install googletrans4.0.0-rc1然后…...

Linux_CentOS_7.9_MySQL_5.7配置数据库服务开机自启动之简易记录

前言&#xff1a; 作为运维保障&#xff0c;都无法准确预估硬件宕机的突发阶段&#xff0c;其生产数据实时在产出&#xff0c;那作为dba数据库服务的其重要性、必要性就突显而出。这里拿虚拟机试验做个配置记录&#xff0c;便于大家学习参考。 # 如出现服务器重启后登入报错无…...

js实现拖动盒子查看内容 内容拖动

一.分析实现过程 1.鼠标拖动的操作是&#xff0c;按下鼠标不松&#xff0c;拖动鼠标&#xff0c;就需要监听鼠标点击事件(onmousedown),鼠标拖动事件(onmousemove) 2.鼠标拖动事件的监听时机&#xff0c;是在按下鼠标之后监听的&#xff0c;所以鼠标拖动事件需要放在鼠标按下事…...

[C#]winform利用seetaface6实现C#人脸检测活体检测口罩检测年龄预测性别判断眼睛状态检测

【官方框架地址】 https://github.com/ViewFaceCore/ViewFaceCore 【算法介绍】 SeetaFace6是由中国科技公司自主研发的一款人脸识别技术&#xff0c;它基于深度学习算法&#xff0c;能够快速、准确地识别出人脸&#xff0c;并且支持多种应用场景&#xff0c;如门禁系统、移动…...

c++ execl 执行 重定向

#include <unistd.h>int main() {pid_t childPid fork(); // 创建子进程if (childPid 0) {// 子进程// 关闭标准输入、输出和错误流close(STDIN_FILENO);close(STDOUT_FILENO);close(STDERR_FILENO);// 打开要写入的文件int fd open("output.txt", O_WRONLY…...

uni-app中实现元素拖动

uni-app中实现元素拖动 1、代码示例 <template><movable-area class"music-layout"><movable-view class"img-layout" :x"x" :y"y" direction"all"><img :src"musicDetail.bgUrl" :class&…...

Java系列-Class.forName和ClassLoader.loadClass的区别

Class.forName 和 ClassLoader.loadClass 是 Java 中两种加载类的方式&#xff0c;它们的主要区别在于加载类的时机和对异常的处理。 1.Class.forName Class.forName 是一个静态方法&#xff0c;用于在运行时加载类。它返回一个 Class 对象&#xff0c;但在加载类的过程中&am…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

Python Einops库:深度学习中的张量操作革命

Einops&#xff08;爱因斯坦操作库&#xff09;就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库&#xff0c;用类似自然语言的表达式替代了晦涩的API调用&#xff0c;彻底改变了深度学习工程…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

Web后端基础(基础知识)

BS架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器架构模式。客户端只需要浏览器&#xff0c;应用程序的逻辑和数据都存储在服务端。 优点&#xff1a;维护方便缺点&#xff1a;体验一般 CS架构&#xff1a;Client/Server&#xff0c;客户端/服务器架构模式。需要单独…...