Go小技巧易错点100例(十九)

本次内容:

  • goto语法和label的使用

正文:

在Go语言中,goto 语句和标签(label)提供了一种跳转到程序中的另一个位置的方式。虽然这种特性在解决某些类型的复杂逻辑时可能很有用,但过度使用 goto 可能会导致代码难以理解和维护。因此,建议谨慎使用,并优先考虑使用循环、条件语句等更结构化的控制流机制。

基本语法

goto 语句的基本语法如下:

goto Label;
...
Label:

这里,Label 是一个标识符,它标记了程序中的一个位置。goto 语句会立即终止当前函数的执行,并将控制流转移到与 Label 关联的语句。

示例

下面是一个简单的示例,展示了如何在Go中使用 goto 和标签:

package mainimport "fmt"func main() {i := 0Here: // Labelfmt.Println(i)i++if i < 5 {goto Here // 跳转到标签Here}fmt.Println("Done")
}

在这个例子中,Here 是一个标签,它标记了 fmt.Println(i)i++ 语句的位置。当 i 小于 5 时,goto Here 会导致程序跳转到 Here 标签处,从而形成一个简单的循环。当 i 不再小于 5 时,循环结束,程序继续执行到 fmt.Println("Done")

注意事项

可读性:虽然 goto 语句在某些情况下很有用,但它可能会降低代码的可读性。其他开发者(或未来的你)在阅读代码时可能会感到困惑,不知道为什么会突然跳转到某个位置。

维护性:如果代码中的逻辑发生变化,可能需要调整 goto 语句和标签的位置,这可能会引入错误或遗漏。

替代方案:在大多数情况下,可以通过使用循环控制语句(如 breakcontinue)、函数返回、错误处理机制等更结构化的方法来替代 goto 语句。

作用域goto 语句只能跳转到当前函数内的标签。它不能跨函数跳转,也不能跳转到定义在块(如 ifforswitch 语句块)内部的标签(但可以跳出这些块)。

限制:Go语言对 goto 的使用施加了一些限制,以避免滥用。例如,你不能从 defer 语句中跳转到另一个地方,因为 defer 语句的执行是在包含它的函数即将返回之前进行的。

总之,虽然 goto 语句在Go语言中是可用的,但你应该谨慎使用它,并优先考虑更结构化和易于理解的替代方案。

goto的使用场景

跳出多重循环
当需要在嵌套的多重循环中直接跳出到循环外部时,使用goto语句可以方便地从最内层循环直接跳出到外层的某个位置,避免了使用多个break语句的繁琐。这在处理复杂的循环逻辑时尤其有用。

错误处理:在Go语言中,尽管goto语句的使用通常被认为应该受到限制,但在某些特定情况下,如错误处理,goto可以作为一种有效的机制来快速跳转到错误处理代码块,避免代码的重复和复杂化。

避免复杂的条件语句:在某些情况下,使用goto语句可以避免编写复杂的条件语句或嵌套循环,使代码更加简洁明了。但需要注意的是,过度使用goto可能会使代码变得难以理解和维护。

label(或Label)的使用场景

与goto配合使用:label主要用于与goto语句配合,标识代码中的某个位置,作为goto语句跳转的目标。这是label在编程语言中的主要用途。

多重循环控制:在处理多重循环时,通过为循环体设置不同的label,可以更加精确地控制循环的跳转行为。例如,可以使用break加上label来跳出指定的循环层。

代码块标识:在某些情况下,label也可以用作代码块的标识,但这种情况相对较少。它更多地是与goto语句一起使用,来实现特定的控制流逻辑。

小练习

下面这两段代码有什么不一样:

第一段代码(使用 break 语句配合标签 BreakPoint2
BreakPoint2:for i := 0; i < 3; i++ {for j := 0; j < 3; j++ {if i*j > 4 {break BreakPoint2}fmt.Println(i, "*", j, "=", i*j)}fmt.Println(i, "*", i)}
第二段代码(使用 goto 语句和标签 BreakPoint
for i := 0; i < 3; i++ {for j := 0; j < 3; j++ {if i*j > 4 {goto BreakPoint}fmt.Println(i, "*", j, "=", i*j)}fmt.Println(i, "*", i)
}
BreakPoint:
fmt.Println("跳出循环")

两段代码是输出结果:

第一段代码:0 * 0 = 0
0 * 1 = 0
0 * 2 = 0
0 * 0
1 * 0 = 0
1 * 1 = 1
1 * 2 = 2
1 * 1
2 * 0 = 0
2 * 1 = 2
2 * 2 = 4
2 * 2第二段代码:0 * 0 = 0
0 * 1 = 0
0 * 2 = 0
0 * 0
1 * 0 = 0
1 * 1 = 1
1 * 2 = 2
1 * 1
2 * 0 = 0
2 * 1 = 2
2 * 2 = 4
2 * 2
跳出循环
对比

第一段代码使用 break 语句和标签来跳出特定的循环层,但不会执行到该标签之后的代码。

  • 在这段代码中,当 i*j > 20 时,break BreakPoint2 会执行,直接跳出到标签 BreakPoint2 指定的位置,即跳出最外层的 for 循环。
  • 注意这里没有打印 “跳出循环” 的消息,因为 break 语句直接终止了 BreakPoint2 标签下的循环,没有执行到 BreakPoint2 标签之后的代码。
  • 循环 fmt.Println(i, "*", i) 只在每个内层循环完整执行一次后(即 j 从 0 遍历到 9)才会执行一次,除非内层循环被 break 提前终止。

第二段代码使用 goto 语句来跳出所有循环,并直接跳转到指定的标签处执行代码,这可能会导致代码执行流程的突然中断,并跳过一些原本计划执行的代码。

  • 在这段代码中,当 i*j > 20 时,goto BreakPoint 会执行,直接跳转到标签 BreakPoint 指定的位置。
  • 这会跳过当前循环的剩余部分(包括内层循环和外层循环中当前迭代之后的所有代码),直接执行到 BreakPoint: 标签后的代码,即打印 “跳出循环”。
  • 因此,一旦触发 goto,不仅内层循环会立即终止,外层循环的当前迭代也会被跳过,且不再继续执行 fmt.Println(i, "*", i)

注意事项

尽管goto和label在某些场景下可以带来便利,但过度使用它们可能会使代码变得难以理解和维护。因此,在使用时应该谨慎考虑,并尽量寻找更清晰的替代方案。

在大多数现代编程语言中,都鼓励使用结构化编程方法(如条件语句、循环和函数调用)来组织代码逻辑,而不是依赖goto和label来实现复杂的控制流。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【SpringBoot】深度解析 Spring Boot 拦截器:实现统一功能处理的关键路径

前言 &#x1f31f;&#x1f31f;本期讲解关于拦截器的详细介绍~~~ &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; 你的点赞就是小编不断更新的最大动力 &#x1f386;那么废话不多说…

网络渗透测试实验四:CTF实践

1.实验目的和要求 实验目的:通过对目标靶机的渗透过程,了解CTF竞赛模式,理解CTF涵盖的知识范围,如MISC、PPC、WEB等,通过实践,加强团队协作能力,掌握初步CTF实战能力及信息收集能力。熟悉网络扫描、探测HTTP web服务、目录枚举、提权、图像信息提取、密码破解等相关工具…

计算机毕业设计Python+Spark考研预测系统 考研推荐系统 考研数据分析 考研大数据 大数据毕业设计 大数据毕设

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

2024年度总结:保持正念 延迟满足

总结&#xff1a; 时光荏苒&#xff0c;很快就到了年底&#xff0c;2024年也就悄悄的过去了&#xff0c;回顾这一年&#xff0c;有很多的感触&#xff0c;在此做一个总结&#xff0c;留下自己的脚印 CTF&#xff1a; 要总结的第一件事那当然是CTF&#xff0c;回顾这一年&#…

LeetCode - 初级算法 数组(存在重复元素)

存在重复元素 这篇文章讨论如何判断一个数组中是否存在重复元素。 免责声明:本文来源于个人知识与公开资料,仅用于学术交流。 描述 给定一个整数数组 nums,如果任一值在数组中出现至少两次,返回 true;如果数组中每个元素互不相同,返回 false。 示例: 输入: nums =…

03-spring-理-DefaultListableBeanFactory

DefaultListableBeanFactory 是 beanFactory的实现 重要 有一些类被注解标注了。但是没有加入到容器。 怎么将标注的类加入到容器&#xff1f; 这个时候使用bean的后置处理器 主要是通过bean后置处理器来处理 被注解标注的类 org.springframework.context.annotation.inter…

绘制三元图、颜色空间图:R语言代码

本文介绍基于R语言中的Ternary包&#xff0c;绘制三元图&#xff08;Ternary Plot&#xff09;的详细方法&#xff1b;其中&#xff0c;我们就以RGB三色分布图为例来具体介绍。 三元图可以从三个不同的角度反映数据的特征&#xff0c;因此在很多领域都得以广泛应用&#xff1b;…

30天开发操作系统 第 10 天 -- 叠加处理

前言 得益于昨天的努力&#xff0c;我们终于可以进行内存管理了。不过仔细一看会注意到&#xff0c;bootpack.c都已经有254行了。笔者感觉这段程序太长了&#xff0c;决定整理一下&#xff0c;分出一部分到memory.c中去。(整理中)…好了&#xff0c;整理完了。现在bootpack.c变…

2024年RAG:回顾与展望

2024年&#xff0c;RAG&#xff08;Retrieval-Augmented Generation&#xff09;技术经历了从狂热到理性的蜕变&#xff0c;成为大模型应用领域不可忽视的关键力量。年初&#xff0c;AI的“无所不能”让市场充满乐观情绪&#xff0c;RAG被视为解决复杂问题的万能钥匙&#xff1…

鸿蒙项目云捐助第三十一讲云捐助项目云前台显示商品列表

鸿蒙项目云捐助第三十一讲云捐助项目云前台显示商品列表 前面完成了云数据库后台的商品批量添加&#xff0c;这里需要把数据放在分类导航页面中显示。 一、云前台显示商品列表 这里需要把商品列表显示在MyNavSliderBar的组件中,MyNavSliderBar组件是通过首页路由实现的,在项…

【brew安装失败】DNS 查询 raw.githubusercontent.com 返回的是 0.0.0.0

从你提供的 nslookup 输出看&#xff0c;DNS 查询 raw.githubusercontent.com 返回的是 0.0.0.0&#xff0c;这通常意味着无法解析该域名或该域名被某些 DNS 屏蔽了。这种情况通常有几个可能的原因&#xff1a; 可能的原因和解决方法 本地 DNS 问题&#xff1a; 有可能是你的本…

【SpringMVC】拦截器

拦截器&#xff08;Interceptor&#xff09;是一种用于动态拦截方法调用的机制。在 Spring MVC 中&#xff0c;拦截器能够动态地拦截控制器方法的执行过程。以下是请求发送与接收的基本流程&#xff1a; 当浏览器发出请求时&#xff0c;请求首先到达 Tomcat 服务器。Tomcat 根…

python使用PyQt5,整套,桌面应用

安装 安装 pip install PyQt55.7.1 pip install PyQtWebEngine1、创建窗口&#xff0c;按百分比划分 from PyQt5.QtGui import QGuiApplication from PyQt5.QtWidgets import QApplication, QWidget # 创建应用程序实例 app QApplication([]) # 创建主窗口 window QWidget(…

018-spring-基于aop的事务控制

1 先配置平台事务管理器 2 在配置 spring提供的advice 3 事务增强的aop 总结&#xff1a; 事务就是要做2个配置&#xff1a; <!-- 1 开启事务管理器 不同的框架对应不同的事务管理器 --> <bean id"transactionManager" class"org.springframework.j…

《向量数据库指南》——Milvus Cloud 2.5:Sparse-BM25引领全文检索新时代

Milvus Cloud BM25:重塑全文检索的未来 在最新的Milvus Cloud 2.5版本中,我们自豪地引入了“全新”的全文检索能力,这一创新不仅巩固了Milvus Cloud在向量数据库领域的领先地位,更为用户提供了前所未有的灵活性和效率。作为大禹智库的向量数据库高级研究员,以及《向量数据…

2025决战智驾:从中阶卷到L3,车企需要抓好一个数据闭环

作者 |王博 编辑 |德新 全国都能开之后&#xff0c;智驾继续走向哪里&#xff1f; 2024年末&#xff0c;大部分主流车企已经实现了无&#xff08;高精度&#xff09;图全国都能开。而第一梯队的玩家&#xff0c;从以规则为主的算法框架&#xff0c;向神经网络模型为主的新架构…

优化大肠杆菌菌株和发酵工艺以提高L-赖氨酸生产-文献精读94

Optimizing Escherichia coli strains and fermentation processes for enhanced L-lysine production: a review 优化大肠杆菌菌株和发酵工艺以提高L-赖氨酸生产&#xff1a;综述 对比酵母酵母中de novo生物合成啤酒花活性类黄酮黄腐醇-文献精读93-CSDN博客 赖氨酸是一种重要…

如何在 Ubuntu 22.04 上安装 Varnish HTTP 教程

简介 在本教程中&#xff0c;我们将学习如何在 Ubuntu 22.04 服务器上安装和配置 Varnish HTTP。 Varnish 是一款高性能的 HTTP 加速器&#xff0c;旨在提高内容密集型动态网站的速度。它通过将网页缓存在内存中来工作&#xff0c;从而减少 Web 服务器的负载&#xff0c;并显…

CPT203 Software Engineering 软件工程 Pt.5 软件测试(中英双语)

文章目录 8. 软件测试8.1 Testing&#xff08;测试&#xff09;8.1.1 A note of testing under the V & A framework8.1.2 The Basics8.1.3 The Goals8.1.4 The Stages 8.2 Developing testing&#xff08;开发测试&#xff09;8.2.1 Unit testing&#xff08;单元测试&…

STM32配合可编程加密芯片SMEC88ST的防抄板加密方案设计

SMEC88ST SDK开发包下载 目前市场上很多嵌入式产品方案都是可以破解复制的&#xff0c;主要是因为方案主芯片不具备防破解的功能&#xff0c;这就导致开发者投入大量精力、财力开发的新产品一上市就被别人复制&#xff0c;到市场上的只能以价格竞争&#xff0c;最后工厂复制的产…