【橘子golang】从golang来谈闭包
一、简介
闭包(Closure)是一种编程概念,它允许函数捕获并记住其创建时的上下文环境(包括变量)。闭包通常用于函数式编程语言,但在许多现代编程语言中也有支持,包括 Go ,Js等支持函数式编程的编程语言。
说的简单一点就是,闭包是一个函数值,它引用了其创建时的自由变量(即非局部变量)。当闭包被调用时,它会访问这些变量的值,即使这些变量在闭包创建时的作用域已经结束。闭包的核心特性包括:
函数值:闭包本质上是一个函数。
捕获上下文:闭包可以捕获并记住其创建时的变量状态。
持久化变量:即使创建闭包的作用域已经结束,闭包仍然可以访问这些变量。
是不是看的很头大,我们来用代码来描述一下。
二、golang中的闭包
golang作为一个现代编程语言,虽然众多褒贬不一但是他确实支持了很多现代编程语言的特点,比如函数编程。
package mainimport ("fmt"
)// 定义一个函数 addCounter,它返回一个匿名函数(闭包)。
func addCounter() func() {// 定义一个局部变量 count,它是一个整数,初始值为 0。// 这个变量是闭包的“状态”,它会被闭包捕获。var count int = 0// 返回一个匿名函数,这个匿名函数可以访问并修改外部的 count 变量。return func() {// 每次调用这个匿名函数时,count 的值会加 1。count += 1// 打印当前 count 的值。fmt.Printf("count is %d\n", count)}
}func main() {var add1 = addCounter()add1() // 输出: 1add1() // 输出: 2
}
这个函数addCounter的特点如下:
1、名称为addCounter
2、入参为空,该函数没有入参。
3、返回值是一个函数,这个返回值函数的类型就更简单了,入参和出参都没有。
但是重点就在于这个addCounter的返回函数,我们来单独看这一段逻辑(我们称之为内部函数):
return func() {// 闭包函数count += 1fmt.Printf("count is %d\n", count)
}
逻辑很简单,就是对count变量做了一个+1的操作,但是这个count不是这个返回函数里面,他是在他的外部函数addCounter中声明的,而这个内部函数就是闭包,返回一个匿名函数(闭包)。这个匿名函数可以访问并修改 addCounter 中的 count 变量。该闭包捕获了来自外部函数的变量,当捕获完成后,此时该变量的生命周期就发生了变化。
具体我们再往下看:
我们在主函数中调用逻辑:
func main() {var add1 = addCounter()add1() // 输出: 1add1() // 输出: 2
}
我们调用var add1 = addCounter(),返回了一个add1变量,此时这就调用了这个外部函数,并且返回了内部函数给add1,注意,此时addCounter()函数调用已经结束了,那么在我们常规的理解中,当一个函数调用结束,函数中创建的变量自然也是结束了,被销毁了(我们没有返回)。但是闭包这里不同,闭包在创建的时候捕获了这个变量count,此时虽然 addCounter调用结束了,但它捕获了 addCounter 中的 count 变量。即使 addCounter 函数的执行结束,count 变量仍然被匿名函数记住,并且可以在后续调用中继续使用。这就是闭包的核心,闭包捕获外部变量,即便外部变量所在的函数已经调用结束了,但是闭包依然可以使用该变量。这就是我们为啥看到的输出1,2.
因为当var add1 = addCounter() 执行,第一个闭包被创建,也就是add1,我们多次执行该闭包,都是能访问该被闭包捕获的变量的。
但是如果我们改成这样。
func main() {var add1 = addCounter()add1() // 输出: 1var add2 = addCounter()add2() // 输出: 1
}
此时就会输出两个1,因为你第二次调用var add2 = addCounter(),此时创建的是一个新的闭包,并将返回的闭包赋值给变量 add2。这里的 add2 是一个独立的闭包,它有自己的 count 变量,重新初始化为0,所以就输出都是1。
这基本就是闭包的概念,这个概念也是因为内部匿名函数封闭并包围作用域中的变量而得名的。
三、总结
闭包的主要特点就是:
捕获变量:闭包捕获了其创建时的变量(如 count),即使这些变量在其原始作用域中已经不可访问,就像我们初始化count的函数addCounter已经结束了,但是他还是被闭包捕获到了。独立状态:每个闭包实例都有自己的独立状态。add1 和 add2 是两个独立的闭包,它们各自维护自己的 count 变量。延迟求值:闭包在被调用时才计算其捕获的变量的值,而不是在创建时。函数式编程的特点大多如此。我们在java中使用lambda作为参数的时候也是如此。
go语言编程规范
effective_go
相关文章:
【橘子golang】从golang来谈闭包
一、简介 闭包(Closure)是一种编程概念,它允许函数捕获并记住其创建时的上下文环境(包括变量)。闭包通常用于函数式编程语言,但在许多现代编程语言中也有支持,包括 Go ,Js等支持函数…...
盛铂科技PDROUxxxx系列锁相介质振荡器(点频源):高精度信号源
——超低相位噪声、宽频覆盖、灵活集成,赋能下一代射频系统 核心价值:以突破性技术解决行业痛点 在雷达、卫星通信、高速数据采集等高端射频系统中,信号源的相位噪声、频率稳定度及集成灵活性直接决定系统性能上限。盛铂科技PDROUxxxx系列锁…...
Linux | Vim 鼠标不能右键粘贴、跨系统复制粘贴
注:本文为 “ Vim 中鼠标右键粘贴、跨系统复制粘贴问题解决方案” 相关文章合辑。 未整理去重。 Linux 入门:vim 鼠标不能右键粘贴、跨系统复制粘贴 foryouslgme 发布时间 2016 - 09 - 28 10:24:16 Vim 基础 命令模式(command - mode&…...
仿12306项目(4)
基本预定车票功能的开发 对于乘客购票来说,需要有每一个车次的余票信息,展示给乘客,供乘客选择,因此首个功能是余票的初始化,之后是余票查询,这两个都是控台端。对于会员端的购票,需要有余票查询…...
调研:如何实现智能分析助手(Agent)(AutoCoder、FastGPT、AutoGen、DataCopilot)
文章目录 调研:如何实现智能分析助手(Agent)(AutoCoder、FastGPT、AutoGen、DataCopilot)一、交互流程二、数据流程三、架构分类四、开源产品4.1 AutoCoder(知识库变体)4.2 FastGPT(…...
爬虫逆向:脱壳工具Youpk的使用详解
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 1. Youpk 简介1.1 Youpk介绍1.2 Youpk支持场景1.3 Youpk基本流程1.4 使用 Youpk 脱壳步骤1.5 常用的脱壳工具对比2. Youpk 的安装与使用2.1 安装 Youpk2.2 使用 Youpk 脱壳3. 脱壳后的 Dex 文件分析3.1 使用 JADX 反编译…...
Java 大视界 -- Java 大数据在智能政务公共服务资源优化配置中的应用(118)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
Java停车平台高并发抢锁技术方案设计 - 慧停宝开源停车管理平台
Java停车平台高并发抢锁技术方案设计 一、业务场景特征 瞬时流量峰值 早晚高峰时段(07:30-09:00, 17:30-19:00)请求量激增10倍热门商圈停车场每秒并发请求可达5000 QPS 资源竞争特性 单个车位被多人同时抢占(超卖风险)用户操作链…...
【论文笔记】Attentive Eraser
标题:Attentive Eraser: Unleashing Diffusion Model’s Object Removal Potential via Self-Attention Redirection Guidance Source:https://arxiv.org/pdf/2412.12974 收录:AAAI 25 作者单位:浙工商,字节&#…...
Android Flow操作符分类
Flow操作符分类...
Cursor + IDEA 双开极速交互
相信很多开发者朋友应该和我一样吧,都是Cursor和IDEA双开的开发模式:在Cursor中快速编写和生成代码,然后在IDEA中进行调试和优化 在这个双开模式的开发过程中,我就遇到一个说大不大说小不小的问题: 得在两个编辑器之间来回切换查…...
图像识别-手写数字识别项目
训练模型: 实现神经网络实例 准备数据 导入torchvision.transforms模块,它提供了许多常用的数据预处理操作,如裁剪、旋转、归一化等。 从torch.utils.data模块导入DataLoader类,用于加载数据集并提供批量处理功能。 导入tensorboa…...
推荐几款优秀的PDF转电子画册的软件
当然可以!以下是几款优秀的PDF转电子画册的软件推荐,内容简洁易懂,这些软件都具有易用性和互动性,适合不同需求的用户使用。 ❶ FLBOOK|在线创作平台 支持PDF直接导入生成仿真翻页电子书。提供15主题模板与字体库&a…...
bert模型笔记
1.各预训练模型说明 BERT模型在英文数据集上提供了两种大小的模型,Base和Large。Uncased是意味着输入的词都会转变成小写,cased是意味着输入的词会保存其大写(在命名实体识别等项目上需要)。Multilingual是支持多语言的࿰…...
利用 ArcGIS Pro 快速统计省域各市道路长度的实操指南
在地理信息分析与处理的工作中,ArcGIS Pro 是一款功能强大的 GIS 软件,它能够帮助我们高效地完成各种复杂的空间数据分析任务。 现在,就让我们一起深入学习如何借助 ArcGIS Pro 来统计省下面各市的道路长度,这一技能在城市规划、…...
数据库系统概论(一)详细介绍数据库与基本概念
数据库系统概论(一)介绍数据库与基本概念 前言一、什么数据库1.数据库的基本概念2.数据库的特点 二、数据库的基本概念1. 数据2. 数据库3.数据库管理系统4.数据库系统 三、数据管理技术的产生和发展四、数据库系统的特点1.数据结构化2.数据共享性3.数据冗…...
数字IC后端实现教程| Clock Gating相关clock tree案例解析
今天小编给大家分享几个跟时钟树综合,clock tree相关的典型问题。 数字IC后端设计实现之分段长clock tree经典案例 Q1:星主好,下面的图是通过duplicate icg来解setup违例的示意图。我没看懂这个 duplicate操作在cts阶段是怎么实现的,用什么…...
build gcc
1,下载源码 wget https://gcc.gnu.org/pub/gcc/infrastructure/mpfr-4.1.0.tar.bz2 wget https://gcc.gnu.org/pub/gcc/infrastructure/gmp-6.1.0.tar.bz2 wget https://gcc.gnu.org/pub/gcc/infrastructure/mpc-1.2.1.tar.gz git clone --mirror https://github…...
软考架构师笔记-计算机网络
1.9 计算机网络 OSI/RM 七层模型 物理层 二进制传输(中继器、集线器) (typedef) 数据链路层 传送以帧为单位的信息(网桥、交换机、网卡) 网络层 分组传输和路由选择(三层交换机、路由器)ARP/RARP/IGMP/ICMP/IP 传输层 端到端的连接(TCP/UDP)在前向纠错系统中,当接…...
ubuntu打包 qt 程序,不用每次都用linuxdeployqt打包
用linuxdeployqt打包太麻烦,每次程序编译都要用linuxdeployqt打包一次,而且每次都要很长时间,通过研究得出一个新的打包方法 1.用用linuxdeployqt得出依赖的库文件(只要没有增加新模块,只要用一次就可以) …...
Spark(6)vm与centos虚拟机
(一)克隆虚拟机 vm软件提供了克隆的功能,它可以允许我们从一台虚拟机上快速克隆出其他的一模一样的主机。 具体的操作步骤如下: 关闭hadoop100这台虚拟机。在它身上右键,并选择管理 → 克隆 命令 在随后的设置中&#…...
人工智能开发面经AI、大数据、算法
以下是一份AI算法开发岗位的面试面经,结合最新行业趋势和经典问题,涵盖技术解析与实战案例,供参考: 一、机器学习基础(占比约30%) 1. 过拟合与欠拟合的解决方案 问题:如何解决模型过拟合&…...
在 macOS 上使用 CLion 进行 Google Test 单元测试
介绍 Google Test(GTest)是 Google 开源的 C 单元测试框架,它提供了简单易用的断言、测试夹具(Fixtures)和测试运行机制,使 C 开发者能够编写高效的单元测试。 本博客将介绍如何在 macOS 上使用 CLion 配…...
NO2.C++语言基础|C++和Java|常量|重载重写重定义|构造函数|强制转换|指针和引用|野指针和悬空指针|const修饰指针|函数指针(C++)
6. C 和 Java 区别(语⾔特性,垃圾回收,应⽤场景等) 指针: Java 语⾔让程序员没法找到指针来直接访问内存,没有指针的概念,并有内存的⾃动管理功能,从⽽有效的防⽌了 C 语⾔中的指针…...
中原银行:从“小机+传统数据库”升级为“OceanBase+通用服务器”,30 +系统成功上线|OceanBase DB大咖说(十五)
OceanBase《DB 大咖说》第 15 期,我们邀请到了中原银行金融科技部数据团队负责人,吕春雷。本文为本期大咖说的精选。 吕春雷是一位资历深厚的数据库专家,从传统制造企业、IT企业、甲骨文公司到中原银行,他在数据库技术与运维管理…...
自注意力机制的演进-从Transformer架构到DeepSeek-R1模型的深度语义理解革新
2025年,我国发布了开创性且高性价比的大语言模型-DeepSeek-R1,推动了AI领域的重大变革。本章节回顾了LLM的发展历程,其起点可追溯至2017年Transformer架构的提出,该架构通过自注意力机制(Self-Attention)彻底革新了自然语言处理技…...
数据结构拓展:详解realloc(C++)
前言 在C中,realloc 是C标准库提供的一个内存管理函数,用于动态调整已分配内存块的大小。尽管C更推荐使用 new/delete 或智能指针,但在某些场景(如与C代码交互或底层内存操作)中仍可能用到 realloc。以下是详细分析&a…...
计算机网络数据传输探秘:包裹如何在数字世界旅行?
计算机网络数据传输探秘:包裹如何在数字世界旅行? 一、从快递网络看数据传输本质 想象你网购了一件商品: 打包:商家用纸箱包装,贴上地址标签(数据封装)运输:包裹经过网点→分拣中心→运输车(网络节点与链路)签收:快递员核对信息后交付(数据校验与接收)数据的网络…...
十二、OSG学习笔记-Control
上一章节: 十一、OSG学习笔记-操作系统接口-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/145891502 本章节代码: OsgStudy/Controls CuiQingCheng/OsgStudy - 码云 - 开源中国https://gitee.com/cuiqingcheng/osg-study/tree/ma…...
DevOps全流程
DevOps全流程 面试速记 DevOps 是一种融合开与运维的软件研发实践方法,规划从需求调研到开发,测试,部署等全流程,通过Jenkins 和Kubernetes 等自动化工具集成部署实现从代码编写到部署的无缝衔接,加速软件交付周期。我…...
ARM Linux LCD上实时预览摄像头画面
文章目录 1、前言2、环境介绍3、步骤4、应用程序编写4.1、lcd初始化4.2、摄像头初始化4.3、jpeg解码4.4、开启摄像头4.5、完整的程序如下 5、测试5.1、编译应用程序5.2、运行应用程序 6、总结 1、前言 本次应用程序主要针对支持MJPEG格式输出的UVC摄像头。 2、环境介绍 rk35…...
NL2SQL-基于Dify+阿里通义千问大模型,实现自然语音自动生产SQL语句
本文基于Dify阿里通义千问大模型,实现自然语音自动生产SQL语句功能,话不多说直接上效果图 我们可以试着问他几个问题 查询每个部门的员工数量SELECT d.dept_name, COUNT(e.emp_no) AS employee_count FROM employees e JOIN dept_emp de ON e.emp_no d…...
centos8更换阿里云yum源
1.centos8更换为阿里云yum源 2.更换阿里云Yum-centos8源 mv /etc/yum.repos.d/CentOS-Stream-BaseOS.repo /etc/yum.repos.d/CentOS-Stream-BaseOS.repo.backupcurl -o /etc/yum.repos.d/CentOS-Stream-BaseOS.repo https://mirrors.aliyun.com/repo/Centos-8.repowget -O /et…...
在命令的轨迹中:创建、删除与查看普通用户,Linux用户管理的风华与深邃
文章目录 引言一、创建普通用户二、测试是否创建成功三、查看普通用户四、更改密码五、赋予普通用户root权限六、删除普通用户小结 引言 在浩瀚如海的Linux系统中,每一位用户都是一颗独立的星辰,散发着属于自己的光芒。在这片数字的星空中,用…...
年后寒假总结及计划安排
年后寒假总结 年后主要学习了微服务,nacos (服务注册中心),feign(远程调用),网关,双token(相较于之前更加规范,更加符合企业级),配置管理 ,mybati…...
IvorySQL v4 逻辑复制槽同步功能解析:高可用场景下的数据连续性保障
功能简介 IvorySQL v4 基于 PostgreSQL 17,引入了逻辑复制槽同步至热备份数据库的功能。这一改进有效解决了旧版本中主数据库与备份数据库切换后逻辑复制中断的问题。对于那些追求数据高可用性和业务连续性的数据库来说,这无疑是一个重大的利好消息。它…...
GitLab常用操作
git init //初始化一个git的本地仓库git rm -r --cached //清除缓存,比如修改了.gitignore文件,可以先清缓存再进行下边的操作git add README.md //增加一个文件 //git add 文件夹/ //增加文件夹内的所有文件 //git add --all //增加当前项目…...
【运维笔记】docker 中 MySQL从5.7版本升级到8.0版本 - 平滑升级
在Docker环境中,将MySQL从5.7版本升级到8.0版本时,数据确实需要迁移。虽然不能直接通过docker-compose命令简单地进行版本升级并保留所有数据,但可以通过一系列步骤来实现平滑升级和数据迁移。以下是详细的迁移步骤: 一、准备阶段…...
NUMA架构介绍
NUMA 架构详解 NUMA(Non-Uniform Memory Access,非统一内存访问) 是一种多处理器系统的内存设计架构,旨在解决多处理器系统中内存访问延迟不一致的问题。与传统的 UMA(Uniform Memory Access,统一内存访问…...
三、0-1搭建springboot+vue3前后端分离-idea新建springboot项目
一、ideal新建项目1 ideal新建项目2 至此父项目就创建好了,下面创建多模块: 填好之后点击create 不删了,直接改包名,看自己喜欢 修改包名和启动类名: 打开ServiceApplication启动类,修改如下: …...
【哇! C++】类和对象(三) - 构造函数和析构函数
目录 一、构造函数 1.1 构造函数的引入 1.2 构造函数的定义和语法 1.2.1 无参构造函数: 1.2.2 带参构造函数 1.3 构造函数的特性 1.4 默认构造函数 二、析构函数 2.1 析构函数的概念 2.2 特性 如果一个类中什么成员都没有,简称为空类。 空类中…...
单片机项目复刻需要的准备工作
一、前言 复刻单片机的项目的时候,有些模块是需要焊接的。很多同学对焊接没有概念。 这里说一下做项目的基本工具。 比如:像这种模块,都需要自己焊接了排针才可以链接的。 二、基本模块 2.1 单排排针 一些模块买回来是没有焊接的&#x…...
Nginx负载均衡配置详解:轻松实现高可用与高性能
在现代Web应用中,负载均衡是确保系统高可用性和高性能的关键技术之一。Nginx作为一款高性能的HTTP服务器和反向代理服务器,其负载均衡功能被广泛应用于各种场景。本文将详细介绍如何使用Nginx实现负载均衡配置,帮助开发者轻松应对高并发和大流…...
SQLAlchemy系列教程:集成Pydantic增强数据处理能力
本教程介绍如何将Pydantic用于数据验证,SQLAlchemy用于数据库操作,从而通过强大的数据处理能力增强Python应用程序。 介绍 在现代web开发中,确保数据的有效性和完整性至关重要。Pydantic和SQLAlchemy是两个功能强大的Python库,可…...
Linux下AWK命令使用方法
文章目录 **一、AWK 基本语法****二、核心概念****1. 内置变量****2. 分隔符****3. BEGIN 和 END 块** **三、常见用法示例****1. 基础打印****2. 条件过滤****3. 计算与统计****4. 字符串操作****5. 处理 CSV 文件** **四、高级用法****1. 使用数组统计****2. 多条件分支&…...
【AI】如何理解与应对AI中的敏感话题:详细分析与实用指南
引言 随着人工智能(AI)技术的不断发展,我们在与AI交互时,可能会遇到敏感话题的讨论限制。在许多情况下,AI系统为了避免触及社会、政治或文化敏感点,会对用户输入进行一定的筛选和过滤。那么,这…...
基于开源库编写MQTT通讯
目录 1. MQTT是什么?2. 开发交互UI3. 服务器核心代码4. 客户端核心代码5. 消息订阅与发布6. 通讯测试7. MQTT与PLC通讯最后. 核心总结 1. MQTT是什么? MQTT(Message Queuing Terlemetry Transport)消息队列遥测协议;是…...
linux指令学习--sudo apt-get install vim
1. 命令分解 部分含义sudo以管理员权限运行命令(需要输入用户密码)。apt-getUbuntu 的包管理工具,用于安装、更新、卸载软件包。installapt-get 的子命令,表示安装软件包。vim要安装的软件包名称(Vim 文本编辑器&…...
PHP之变量
在你有别的编程语言的基础下,你想学习PHP,可能要了解的一些关于变量的信息。 PHP中的变量不用指定数据类型,同时必须用$开头。 全局变量 可以在除函数外任意地方访问,如果需要在函数中访问要先获取 $x 111; function tt() {gl…...
代码规范和简化标准
代码规范和简化标准是编写高质量、可维护、可扩展和可读代码的基本原则。遵循这些标准不仅能提高团队协作效率,还能减少出错的概率和后期维护的成本。以下是一些常见的代码规范和简化标准: 1. 命名规范 变量命名: 使用具有描述性的名称&…...