【Go 基础篇】Go语言匿名函数详解:灵活的函数表达式与闭包
介绍
在Go语言中,函数是一等公民,这意味着函数可以像其他类型的值一样被操作、传递和赋值。匿名函数是一种特殊的函数,它没有固定的函数名,可以在代码中被直接定义和使用。匿名函数在Go语言中具有重要的地位,它们常用于实现闭包、函数式编程和并发编程等领域。
本篇博客将深入探讨Go语言中匿名函数的概念、定义方式、使用场景以及与闭包的关系。通过学习匿名函数,您将能够更加灵活地使用函数表达式,编写更具表达力和可维护性的代码。
匿名函数的基本概念
什么是匿名函数?
匿名函数,也称为函数字面值或函数表达式,是一种没有名称的函数。它允许我们在需要时内联定义函数,并将其作为值传递、赋值给变量或直接调用。
匿名函数的语法结构为:
func(parameters) returnType {// 函数体
}
其中,parameters 是参数列表,returnType 是返回类型,函数体包含了函数的具体实现。
匿名函数的定义和调用
匿名函数的定义可以直接写在代码中,也可以赋值给变量,然后通过变量调用。
// 直接定义匿名函数并调用
result := func(x, y int) int {return x + y
}(3, 5)// 赋值给变量后调用
addFunc := func(x, y int) int {return x + y
}
result := addFunc(3, 5)
匿名函数的使用场景
函数作为参数
匿名函数常用于将函数作为参数传递给其他函数,实现更灵活的行为。这种模式在函数式编程中尤为常见,可以让函数变得更加通用和可复用。
func operate(x, y int, op func(int, int) int) int {return op(x, y)
}result1 := operate(3, 5, func(x, y int) int {return x + y
})result2 := operate(3, 5, func(x, y int) int {return x * y
})
闭包的实现
匿名函数在Go语言中常用于创建闭包(Closure)。闭包是指一个函数包含了它外部作用域中的变量,即使在外部作用域结束后,这些变量依然可以被内部函数访问和修改。
func counter() func() int {count := 0return func() int {count++return count}
}c1 := counter()
fmt.Println(c1()) // 输出 1
fmt.Println(c1()) // 输出 2c2 := counter()
fmt.Println(c2()) // 输出 1
在上面的示例中,counter() 函数返回一个匿名函数,这个匿名函数形成了闭包,持有了外部作用域中的 count 变量。
并发编程
在并发编程中,匿名函数常用于并发执行任务。通过匿名函数,我们可以在一个新的goroutine中执行代码块,实现并发的执行。
func main() {go func() {// 在新的goroutine中执行的匿名函数fmt.Println("Hello from goroutine!")}()// 主goroutine 继续执行其他操作
}
匿名函数的闭包特性
闭包是匿名函数的一个重要特性,它使得匿名函数可以捕获外部作用域中的变量,并在函数内部使用。通过闭包,我们可以实现状态的保持和共享,创建更加灵活和复杂的功能。
捕获变量
在匿名函数内部,可以访问外部作用域中的变量。这些被访问的变量会被匿名函数持有,即使外部作用域结束,这些变量的值也不会被销毁。
func makeCounter() func() int {count := 0return func() int {count++return count}
}counter1 := makeCounter()
fmt.Println(counter1()) // 输出 1
fmt.Println(counter1()) // 输出 2counter2 := makeCounter()
fmt.Println(counter2()) // 输出 1
共享状态
闭包使得多个匿名函数可以共享同一个外部变量的状态。这在一些需要共享状态的情况下非常有用,例如计数器、状态机等。
func makeAdder(increment int) func(int) int {sum := 0return func(x int) int {sum += incrementreturn sum + x}
}add5 := makeAdder(5)
fmt.Println(add5(3)) // 输出 8
fmt.Println(add5(2)) // 输出 15add10 := makeAdder(10)
fmt.Println(add10(3)) // 输出 13
fmt.Println(add10(2)) // 输出 25
在上面的示例中,makeAdder 函数返回一个匿名函数,这个匿名函数持有了外部变量 sum。不同的 makeAdder 调用会创建不同的闭包实例,它们共享了不同的 sum 变量。
匿名函数的注意事项
闭包中的变量生命周期
由于闭包持有外部变量的引用,当闭包存在时,外部变量的生命周期会被延长。如果闭包中的变量一直被持有,可能会导致一些意外的内存泄漏。
func counter() func() int {count := 0return func() int {count++return count}
}c := counter()
fmt.Println(c()) // 输出 1// c仍然持有count变量的引用,count不会被回收
并发访问
在并发编程中,由于闭包可以共享外部变量,可能会导致多个goroutine并发地访问和修改同一个变量,从而引发竞态条件和数据不一致问题。在并发场景下使用闭包时,应当确保访问变量的安全性。
总结
匿名函数是Go语言中的重要特性之一,它允许我们在需要时直接定义和使用函数,实现更灵活的编程。匿名函数常用于函数式编程、闭包的实现、并发编程等领域。通过匿名函数,我们可以将函数作为参数传递、实现闭包、共享状态和实现并发任务。然而,需要注意闭包中变量的生命周期和并发访问的问题,以保证代码的正确性和性能。
通过深入了解匿名函数,您将能够在代码中更加灵活地使用函数表达式,实现更具表达力和可维护性的代码。匿名函数的强大特性使得Go语言在函数式编程和并发编程领域拥有更大的优势,为开发者提供了更多的选择和工具。
相关文章:
【Go 基础篇】Go语言匿名函数详解:灵活的函数表达式与闭包
介绍 在Go语言中,函数是一等公民,这意味着函数可以像其他类型的值一样被操作、传递和赋值。匿名函数是一种特殊的函数,它没有固定的函数名,可以在代码中被直接定义和使用。匿名函数在Go语言中具有重要的地位,它们常用…...
MobileNet、MobileNetV2和MobileNetV3创新点总结
当谈论MobileNet、MobileNetV2和MobileNetV3时,我们指的是一系列基于深度学习的轻量级神经网络架构,这些架构旨在在保持高度准确性的同时减少模型的计算和参数量。以下是它们各自的创新点的详细总结: MobileNet: 深度可分离卷积&…...
算法:数据转换处理2(云台显控)
#define DISPLAYFUNC #include"define.h" extern OS_EVENT *KEYMsg; uchar mBlank[21] = " " ; u c h a r s t r v g a [ ] = " 0.00 V "; uchar str_vga[] = "0.00V...
让大数据平台数据安全可见-行云管家
数字化经济在快速发展,大数据时代已经到来,大数据已经成为企业和政府决策的重要依据。然而大数据行业快速发展所带来的一系列安全问题也继续解决,例如数据安全更难保障,例如认证体系不完善等等。为此行云管家推出了大数据平台数据…...
微信小程序开发教学系列(3)- 页面设计与布局
3. 页面设计与布局 在微信小程序开发中,页面的设计和布局是非常重要的。一个好的页面设计可以提升用户体验,并使小程序更加吸引人。本章节将介绍如何设计和布局微信小程序的页面。 3.1 页面结构和样式的创建和设置 在创建微信小程序页面时,…...
基于JSP+Servlet+mysql员工权限管理系统
基于JSPServletmysql员工权限管理系统 一、系统介绍二、功能展示四、其他系统实现五、获取源码 一、系统介绍 项目类型:Java web项目 项目名称:基于JSPServlet的员工权限管理系统[qxxt] 项目架构:B/S架构 开发语言:Java语言 …...
Qt 自定义提示框 右下角冒泡
网页右下角上经常会出现一些提示性的信息,B/S有的东西,C/S当然也可以有,就像QQ的消息提示一样! 实现一个类似的东西并不困难,只要想明白原理实现起来就很简单了! 实现原理: (1&#…...
js、PHP连接外卖小票机打印机方案(调用佳博、芯烨等)
前言: 目前开发需要用到电脑直接连接外卖小票机打印小票,查阅各种资料,使用 6612345浏览器 终于解决了这个问题。 效果: PHP、js直接连接小票机并且自动出票。 支持的小票机: 目前测试可以的有:电脑A4打印…...
window定时备份MySQL数据库,默认备份7天,一小时备份一次
echo off setlocalrem 在Windows中添加任务计划以执行批处理脚本,请按照以下步骤操作:rem 打开Windows的“任务计划程序”应用程序。你可以通过按下Win R键,在运行对话框中输入taskschd.msc,然后按回车键来打开它。rem 在任务计划…...
正则中常见的流派及其特性
目前正则表达式主要有两大流派(Flavor):POSIX 流派与 PCRE 流派。 1、 POSIX 流派 POSIX 规范定义了正则表达式的两种标准: BRE 标准(Basic Regular Expression 基本正则表达式);ERE 标准&am…...
.net6.0引用的dll放置单独的文件夹
.net6.0 采用原有的设置方法不起作用 <?xml version"1.0" encoding"utf-8" ?> <configuration><startup> <supportedRuntime version"v4.0" sku".NETFramework,Versionv4.8" /></startup><runtim…...
CMake:检测外部库---自定义find模块
CMake:检测外部库---自定义find模块 导言项目结构CMakeLists.txt附录 导言 上一篇,我们了解了CMake其中一种自定义检测外部库的方式,本篇将展示通过编写一个find模块来定位系统上的ZeroMQ库,以便能够在非Unix操作系统上检测该库。 项目结构…...
vue直接使用高德api
第一步:在index.html 引入 <script src"https://webapi.amap.com/maps?v2.0&key你的key"></script>第二步:在你需要地图的时候 放入 <template><div style"width: 200px; height: 200px"><div id&q…...
Setting
目录 1 Setting 1.1.1 getChildList 1.1.2 getGroupList 1.1.3 setListener setOnChildClickListenermSettingList.setOnChildClickListener(new OnChildClickListener() {onChildClick...
时序预测 | Matlab实现SO-CNN-BiGRU蛇群算法优化卷积双向门控循环单元时间序列预测
时序预测 | Matlab实现SO-CNN-BiGRU蛇群算法优化卷积双向门控循环单元时间序列预测 目录 时序预测 | Matlab实现SO-CNN-BiGRU蛇群算法优化卷积双向门控循环单元时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 时序预测 | Matlab实现SO-CNN-BiGRU蛇群算法优化…...
论文浅尝 | KRACL-利用图上下文和对比学习的稀疏KG补全
笔记整理:李娟,浙江大学博士,研究方向为知识图谱表示学习 论文链接:https://arxiv.org/pdf/2208.07622.pdf 代码链接:https://github.com/TamSiuhin/KRACL 介绍 知识图谱(KG)通常是不完整的&…...
【C++】右值引用,移动语义,完美转发
目录 右值引用移动语义拷贝构造与移动构造 万能引用与完美转发 右值引用 左值:可以出现在赋值符号的左边和右边,左值可以取地址。 右值:右值可以出现在赋值符号右边,不能出现在左边,右值不能取地址。 左值/右值引用就…...
【AI】即使AI 时代,程序员也无需焦虑
🚀欢迎来到本文🚀 🍉个人简介:陈童学哦,目前学习C/C、算法、Python、Java等方向,一个正在慢慢前行的普通人。 🏀系列专栏:陈童学的日记 💡其他专栏:CSTL&…...
Django实现DRF数据API接口格式封装
通常在进行前后端分离开发的时候,前端Vue调用后端接口都需要一个状态信息以及数据结合起来的数据。 如果是没有经过加工的API接口访问的数据一般是这样的。 [{"id": 1, "type": "1", "start": "2023-08-24", "end&qu…...
[Go版]算法通关村第十三关白银——数字数学问题之数组实现加法、幂运算
目录 数组实现加法专题题目:数组实现整数加法思路分析:数组末尾开始,逐个元素1,10就进位,!10就退出复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( n ) O(n) O(n)Go代码 题目:字符串加法…...
深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving
地址:LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂,正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...
【若依】框架项目部署笔记
参考【SpringBoot】【Vue】项目部署_no main manifest attribute, in springboot-0.0.1-sn-CSDN博客 多一个redis安装 准备工作: 压缩包下载:http://download.redis.io/releases 1. 上传压缩包,并进入压缩包所在目录,解压到目标…...
MeshGPT 笔记
[2311.15475] MeshGPT: Generating Triangle Meshes with Decoder-Only Transformers https://library.scholarcy.com/try 真正意义上的AI生成三维模型MESHGPT来袭!_哔哩哔哩_bilibili GitHub - lucidrains/meshgpt-pytorch: Implementation of MeshGPT, SOTA Me…...
