go 闭包case

news/2025/2/21 4:21:36/文章来源:https://www.cnblogs.com/maidongdong/p/18723263

你提到的代码片段是一个匿名函数,并且它在定义后立即执行(即 IIFE,立即执行函数表达式)。这个匿名函数内部对 z = x / y 的赋值操作能够影响到外部变量的原因在于 Go 语言的作用域规则和闭包机制。

解释

  1. 闭包机制

    • 匿名函数可以访问其定义时所在作用域中的变量。这种特性称为闭包。在你的例子中,匿名函数捕获了外部的 zxy 变量。
  2. 变量作用域

    • 如果 zxy 是在匿名函数外部声明的变量(例如在 main 函数中),那么这些变量是全局可见的,或者至少在匿名函数的作用域链中是可见的。
    • 当你在匿名函数内部修改这些变量时,实际上是在修改这些变量的原始内存位置,因此这些变化会反映到外部。
  3. 立即执行函数表达式 (IIFE)

    • 匿名函数定义后立即执行,这意味着它的副作用(如变量赋值)会立即生效。

示例代码分析

假设完整的代码如下:

package mainimport "fmt"func main() {var x, y, z intx = 10y = 2func() {defer func() {if r := recover(); r != nil {fmt.Println("recovered from ", r)}}()z = x / y}()fmt.Println("Result:", z) // 输出: Result: 5
}

在这个例子中:

  • xyz 是在 main 函数中声明的变量。
  • 匿名函数捕获了这些变量,并在其内部进行了 z = x / y 的计算。
  • 由于 z 是在 main 函数中声明的,因此匿名函数内部对 z 的修改会影响到 main 函数中的 z

关键点总结

  • 闭包:匿名函数可以访问并修改其定义时所在作用域中的变量。
  • 立即执行:匿名函数定义后立即执行,其副作用会立即生效。
  • 变量作用域:如果变量在外部作用域中声明,则匿名函数内部可以访问和修改这些变量。

注意事项

  • 确保 y 不为零,以避免除零错误。你可以添加检查逻辑来防止这种情况发生。
func main() {var x, y, z intx = 10y = 2func() {defer func() {if r := recover(); r != nil {fmt.Println("recovered from ", r)}}()if y == 0 {panic("division by zero")}z = x / y}()fmt.Println("Result:", z)
}

这样可以确保程序在 y 为零时不会崩溃,并且能够正确恢复。

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

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

相关文章

只需简单5步,Ansible脚本自动搭建AlwaysOn集群(已测试通过,可实际运行)

只需简单5步,Ansible脚本自动搭建AlwaysOn集群(已测试通过,可实际运行)之前已经介绍过这套脚本,请看下面↓ 一分钟搞定!CentOS 7.9上用Ansible自动化部署SQL Server 2019 注意: 这套ansible脚本不支持RHEL 7.X 和CentOS7.X系统! 这套ansible脚本不支持RHEL 7.X …

[AI/计算机硬件] 部署、训练AI大模型的显卡采购指南 [转]

序截至2025年,全球主流的AI大模型满血版的参数量均已突破百亿级,算力需求正以指数级飙升。特别是 DeepSeek 公司旗下的 R1 系列模型的问世,推动了很多中小企业部署私有化模型的需求。然而,面对动辄数十万上百万元的GPU采购成本,选错一块显卡可能让企业付出高昂的试错代价。…

清华DeepSeek手册第Ⅳ版《DeepSeek﹢智灵DeepResearch 让科研像聊天一样简单》

在数字化浪潮汹涌澎湃的当下,大模型如同一颗璀璨新星,强势崛起并迅速成为科技领域的焦点。从最初的理论探索到如今在各个行业的广泛应用,大模型正以惊人的速度重塑着我们的生活与工作模式。 它的出现不仅是人工智能技术发展的重大突破,更是推动经济增长、提升社会治理效能、…

[Vite] Code Splitting Vite

Code Splitting 打包构建中的代码拆分(Code Splitting)是一种优化技术,它将应用程序的代码拆分成多个小块(chunks),并在需要时按需加载这些代码块。这种技术的目的是提高应用程序的性能和用户体验,主要有以下几个原因:减少初始加载时间 当应用程序的代码被打包成一个单…

ArrayBlockingQueue的poll方法底层原理

一、ArrayBlockingQueue的poll方法底层原理 ArrayBlockingQueue 是 Java 并发包 (java.util.concurrent) 中的一个基于数组实现的有界阻塞队列。它的 poll() 方法是用于从队列中移除并返回队首元素的核心方法之一。与 take() 方法不同,poll() 方法在队列为空时不会阻塞,而是立…

java web前台技术的初步学习

今日学习了Java Web 基本开发技术前台技术,分为HTML和CSS HTML 是构建网页结构的基础,用于定义网页中的各种元素,如标题、段落、图片、链接、表格等。通过不同的标签组合,可以搭建出网页的基本框架。 常用标签示例 html示例页面这是一级标题这是一个段落。访问示例网站CSS …

蜜罐-Hfish

一、蜜罐简介 1.1蜜罐技术 ​ 蜜罐技术本质上是一种对攻击方进行欺骗的技术,通过布置一些作为诱饵的主机、网络服务或者信息,诱使攻击方对它们实施攻击。从而可以对攻击行为进行捕获和分析,了解攻击方所使用的工具与方法,推测攻击意图和动机,能够让防御方清晰地了解他们所…

mybatis和mybatis-plus的依赖冲突错误

mybatis-plus底层依托于mybatis,集成了mybatis的依赖,二者都留着,一定程度上会产生版本冲突错误

Schrder-Bernstein定理

Schrder-Bernsteins Theorem 对任意集合\(A,B\),若\(f: A \to B\)与\(g: B \to A\)都是单射,那么存在\(A\to B\)的双射。 Context 设\(f: A \to B, g: B \to A\)是单射。假设\(A,B\)都是有限集,那么该结论是显然的,\(f,g\)本身就是这个双射。否则,说明\(|B|>|A|\)而由\…

ArrayBlockingQueue的take()底层原理

一、ArrayBlockingQueue 的 take() 方法的底层源码的详细介绍 ArrayBlockingQueue 是 Java 并发包 (java.util.concurrent) 中的一个基于数组实现的有界阻塞队列。它的 take() 方法是用于从队列中移除并返回队首元素的核心方法之一。当队列为空时,take() 方法会阻塞当前线程,…

【CodeForces训练记录】Educational Codeforces Round 174 (Rated for Div. 2)

训练情况赛后反思 被英语读题背刺了,原来 C 题里面的 an element 不是 exacly one element 的意思,是 at least one element,读错题被一直硬控,这题没做出来的死因是高中组合数学。 A题 我们手玩样例可以发现 101 的情况必定不合法,abcd,第一个1说明abc相等,第三个1说明…