Go中第一类函数
什么是第一类函数?
支持第一类函数的语言允许将函数分配给变量,作为参数传递给其他函数,并从其他函数返回。Go 支持第一类函数。
在本教程中,我们将讨论第一类函数的语法和各种用例。
匿名函数
让我们从一个简单的例子开始,它为变量分配一个函数。
package mainimport ("fmt"
)func main() {a := func() {fmt.Println("hello world first class function")}a()fmt.Printf("%T", a)
}
Run in playground
在上面的程序中,我们为第 8 行中的变量分配了一个函数。这是将函数分配给变量的语法。如果您仔细观察,分配的函数没有名称。**这些类型的函数称为匿名函数,因为它们没有名称。
调用此函数的唯一方法是使用变量 。我们在下一行中已经完成了此操作。 调用该函数,我们打印变量的类型。
运行此程序将打印
hello world first class function
func()
也可以调用匿名函数而不将其分配给变量。让我们看看在下面的示例中是如何完成的。
package mainimport ("fmt"
)func main() {func() {fmt.Println("hello world first class function")}()
}Run in playground
在上面的程序中,在第 8 行中定义了一个匿名函数,在函数定义之后,我们立即在第 10 行中调用该函数。该程序将输出
hello world first class function
It is also possible to pass arguments to anonymous functions just like any other function.
 1package main23import (4	"fmt"5)67func main() {8	func(n string) {9		fmt.Println("Welcome", n)
10	}("Gophers")
11}
GO
Run in playground
在上面的程序中,将一个字符串参数传递给第一行的匿名函数。运行这个程序将打印
Welcome Gophers
用户自定义函数类型
就像定义自己的结构类型一样,也可以定义自己的函数类型。
type add func(a int, b int) int
创建了一个新的函数类型,它接受两个整数参数并返回一个整数。
让我们编写一个程序
package mainimport ("fmt"
)type add func(a int, b int) intfunc main() {var a add = func(a int, b int) int {return a + b}s := a(5, 6)fmt.Println("Sum", s)
}Run in playground
在上面的程序中,第10行定义一个类型的变量,并给它赋值一个签名与该类型匹配的函数。我们在第13行调用这个函数。并将结果赋值给s。这个程序将打印
Sum 11
高阶函数
高阶函数的定义是一个至少完成以下一项的函数
- 接受一个或多个函数作为参数
- 返回一个函数作为结果
让我们看一下上面两个场景的一些简单示例。
将函数作为参数传递给其他函数
package mainimport ("fmt"
)func simple(a func(a, b int) int) {fmt.Println(a(60, 7))
}func main() {f := func(a, b int) int {return a + bsimple(f)
}Run in playground
在上面的例子中,在第 7 行中,我们定义了一个simple函数,该函数接受一个接受两个 int 参数并返回一个 int 作为参数的函数。在第 12 行的 main 函数中,我们创建一个匿名函数f,其签名与函数的参数匹配simple。我们在下一行中调用并作为参数传递给它。此程序打印为输出。
67
现在让我们重写上面的程序并从simple函数中返回一个函数。
package mainimport ("fmt"
)func simple() func(a, b int) int {f := func(a, b int) int {return a + b}return f
}func main() {s := simple()fmt.Println(s(60, 7))
}Run in playground
在上面的程序中,第 7 行中的简单函数返回一个函数,该函数接受两个参数并返回一个参数。
这个简单的函数是从第 15 行调用的。simple 的返回值分配给s 。现在s包含 function 返回的函数simple。我们s在第 1 6行调用并传递两个 int 参数。该程序输出67。
闭包
闭包是匿名函数的一种特殊情况。闭包是访问函数体外部定义的变量的匿名函数。
举个例子会让事情变得更清楚。
package mainimport ("fmt"
)func main() {a := 5func() {fmt.Println("a =", a)}()
}Run in playground
在上面的程序中,匿名函数访问第 10 行中存在于其主体外部的变量a。因此,这个匿名函数是一个闭包。
每个闭包都绑定到其自己的周围变量。让我们通过一个简单的例子来理解这意味着什么。
package mainimport ("fmt"
)func appendStr() func(string) string {t := "Hello"c := func(b string) string {t = t + " " + breturn t}return c
}func main() {a := appendStr()b := appendStr()fmt.Println(a("World"))fmt.Println(b("Everyone"))fmt.Println(a("Gopher"))fmt.Println(b("!"))
}Run in playground
在上面的程序中,函数appendStr返回一个闭包。该闭包绑定到变量t。让我们来理解这意味着什么。
变量a和b在17, 18行号中声明。 是闭包,它们与自己的值 绑定t。
我们首先a使用World参数进行调用。a现在的版本的值t变为Hello World。
在20 行号中。我们b用Everyone参数调用。由于b绑定到它自己的变量t,因此 b的版本再次t具有初始值Hello。因此,在此函数调用之后, t 的版本的值变为Hello Everyone。该程序的其余部分是不言自明的。
该程序将打印,
Hello World
Hello Everyone
Hello World Gopher
Hello Everyone !
一类函数的实际应用
到目前为止,我们已经定义了什么是第一类函数,并且我们已经看到了一些人为的例子来了解它们是如何工作的。现在让我们编写一个具体的程序来展示第一类函数的实际用法。
我们将创建一个程序,根据某些标准过滤一部分学生。让我们一步一步地解决这个问题。
首先,让我们定义学生类型。
type student struct {firstName stringlastName stringgrade stringcountry string
}下一步是编写函数filter。该函数采用一部分学生和一个确定学生是否符合过滤条件的函数作为参数。一旦我们编写了这个函数,我们就会更好地理解。让我们继续去做吧。
func filter(s []student, f func(student) bool) []student {var r []studentfor _, v := range s {if f(v) == true {r = append(r, v)}}return r
}在上面的filter函数中,第二个参数是一个以student作为参数并返回的函数bool。此函数确定特定学生是否符合条件。第 3 行我们循环的学生切片。我们将每个学生作为参数传递给函数f。如果返回true,则意味着该学生已通过过滤条件并且他被添加到切片中r。你可能对这个函数的实际用途有点困惑,但是一旦我们完成程序就会清楚了。我已经添加了主要功能并在下面提供了完整的程序。
package mainimport ("fmt"
)type student struct {firstName stringlastName  stringgrade     stringcountry   string
}func filter(s []student, f func(student) bool) []student {var r []studentfor _, v := range s {if f(v) == true {r = append(r, v)}}return r
}func main() {s1 := student{firstName: "Naveen",lastName:  "Ramanathan",grade:     "A",country:   "India",}s2 := student{firstName: "Samuel",lastName:  "Johnson",grade:     "B",country:   "USA",}s := []student{s1, s2}f := filter(s, func(s student) bool {if s.grade == "B" {return true}return false})fmt.Println(f)
}Run in playground
main 函数中,我们首先创建两个学生s1并将s2他们添加到 slice 中s。现在假设我们想要找出所有有 Grade 的学生B。我们在上面的程序中通过传递一个函数来建立这一点,该函数检查学生是否有成绩B,如果有则返回 true。上面的程序将打印
[{Samuel Johnson B USA}]
假设我们想找到所有来自印度的学生。通过将函数参数更改为过滤器函数,可以轻松完成此操作。 我在下面提供了执行此操作的代码,
c := filter(s, func(s student) bool {if s.country == "India" {return true}return false
})
fmt.Println(c)请将其添加到 main 函数并检查输出。
让我们再编写一个程序来结束本节。该程序将对切片的每个元素执行相同的操作并返回结果。例如,如果我们想要将切片中的所有整数乘以 5 并返回输出,则可以使用一等函数轻松完成。这些对集合中的每个元素进行操作的函数称为map函数。我提供了下面的程序。这是不言自明的。
package mainimport ("fmt"
)func iMap(s []int, f func(int) int) []int {var r []intfor _, v := range s {r = append(r, f(v))}return r
}
func main() {a := []int{5, 6, 7, 8, 9}r := iMap(a, func(n int) int {return n * 5})fmt.Println(r)
}Run in playground
上面的程序会打印,
[25 30 35 40 45]
相关文章:
Go中第一类函数
什么是第一类函数? 支持第一类函数的语言允许将函数分配给变量,作为参数传递给其他函数,并从其他函数返回。Go 支持第一类函数。 在本教程中,我们将讨论第一类函数的语法和各种用例。 匿名函数 让我们从一个简单的例子开始&am…...
Linux内核分析(五)--IO机制原理与系统总线
目录 一、引言 二、I/O设备 ------>2.1、块设备 ------>2.2、字符设备 ------>2.3、设备控制器 ------------>2.3.1、I/O寻址 ------------>2.3.2、内存映射 I/O 三、系统总线 ------>3.1、数据总线 ------>3.2、地址总线 ------>3.3、控制…...
 
oracle-sql语句执行过程
客户端输入sql语句。 sql语句通过网络到达数据库实例。 服务器进程(server process)接收到sql语句。 sql – 解析成执行计划,然后sql才能执行。 会将sql和sql的执行计划缓存到共享池中。解析: 会消耗很多资源。 从数据库找数据,先从buffer cache中找&a…...
 
京东数据分析:2023年9月京东打印机行业品牌销售排行榜
鲸参谋监测的京东平台9月份打印机市场销售数据已出炉! 鲸参谋数据显示,今年9月,京东平台打印机的销量为60万,环比增长约32%,同比下滑约25%;销售额为5亿,环比增长约35%,同比下滑约29%…...
Flutter 自签名证书
前言 Flutter项目中服务器使用了自签名证书,如果直接使用https请求或者wss请求的话会报证书签名错误。 HandshakeException: Handshake error in client (OS Error: I/flutter (28959): │ 💡 CERTIFICATE_VERIFY_FAILED: unable to get local issuer c…...
 
观察者模式——解决解耦的钥匙
● 观察者模式介绍 观察者模式是一个使用频率非常高的模式,它最常用的地方是GUI系统、订阅——发布系统。因为这个模式的一个重要作用就是解耦,将被观察者和观察者解耦,使得它们之间依赖性更小,甚至做到毫无依赖。以CUI系统来说&a…...
MATLAB和西门子SMART PLC UDP通信
MATLAB和SMART PLC的OPC通信请参考下面文章链接,这里不再赘述: MATLAB和西门子SMART PLC OPC通信-CSDN博客文章浏览阅读661次,点赞26次,收藏2次。西门子S7-200SMART PLC OPC软件的下载和使用,请查看下面文章Smart 200PLC PC Access SMART OPC通信_基于pc access smart的o…...
 
打造高效运营底座,极智嘉一体化软件系统彰显科技威能
在仓储成本和物流需求日益增加的今天,创新且高效的物流机器人解决方案能够显著提升物流运营效率,降低物流成本,实现智能化、精益化、一体化的物流管理。全球仓储机器人引领者极智嘉(Geek)以「一套系统,天生全能」为准则࿰…...
 
sqlsugar查询数据库下的所有表,批量修改表名字
查询数据库中的所有表 using SqlSugar;namespace 批量修改数据库表名 {internal class Program{static void Main(string[] args){SqlSugarClient sqlSugarClient new SqlSugarClient(new ConnectionConfig(){ConnectionString "Data Source(localdb)\\MSSQLLocalDB;In…...
 
如何用 GPT-4 全模式(All Tools)帮你高效学习和工作?
「十项全能」的 ChatGPT ,用起来感受如何? 之前,作为 ChatGPT Plus 用户,如果你集齐下面这五个模式,就会成为别人羡慕的对象。 但现在,人们更加期盼的,是下面这个提示的出现: 这个提…...
 
Cesium 展示——移动拖拽实体
文章目录 需求分析需求 将移动实体的事件加入右键中 ,实现移动拖拽实体,实现对实体的拖拽 移动前 移动后 分析 当鼠标按下时获取该实体。用viewer.scene.pick 来进行获取实体,并锁定相机(需加判断如果不是实体不能锁定相机)// 左键按下事件leftDownAction(e)...
 
javaSE学习笔记-未完
目录 前言 一、java基础 1.1概述 1.java语言发展史 2.Java语言版本 3.Java语言平台 4.Java语言特点 5.Java语言跨平台原理-可移植性 6.JRE和JDK的概述 7.JDK的下载和安装 8.JDK安装路径下的目录解释 9.path环境变量的作用及配置方式 10.classpath环境变量的作用及…...
 
分享一下微信小程序里怎么创建会员卡功能
在当今的数字化时代,微信小程序已经成为一种广泛使用的应用模式,涵盖了各种行业。对于企业而言,拥有一个会员卡系统可以更好地管理客户,提高客户忠诚度,并促进消费。本文将探讨如何在微信小程序中创建会员卡功能&#…...
 
吴恩达《机器学习》5-6:向量化
在深度学习和数值计算中,效率和性能是至关重要的。一个有效的方法是使用向量化技术,它可以显著提高计算速度,减少代码的复杂性。接下来将介绍向量化的概念以及如何在不同编程语言和工具中应用它,包括 Octave、MATLAB、Python、Num…...
 
《面向对象软件工程》笔记——1-2章
“学习不仅是一种必要,而且是一种愉快的活动。” - 尼尔阿姆斯特朗 文章目录 第一章 面向对象软件工程的范畴历史方面经济方面维护方面现代软件维护观点交付后维护的重要性 需求、分析和设计方面团队开发方面没有计划,测试,文档阶段的原因面向…...
 
1400台光刻机,ASML突然大举倾销,外媒惊呼中国芯片进展太快了
就在各方还认为中国芯片在高端芯片方面难以突破的时候,ASML却突然公布了重大消息,累计向中国交付的光刻机已达到1400台,中国已成为ASML的最大市场,这样的消息无疑让外媒颇为震惊。 发生这些变化,在于中国芯片近期所取得…...
 
Leetcode—187.重复的DNA序列【中等】
2023每日刷题(二十) Leetcode—187.重复的DNA序列 实现代码 class Solution { public:const int L 10;vector<string> findRepeatedDnaSequences(string s) {unordered_map<string, int> str;vector<string> ans;int len s.size()…...
 
inno setup 运行时进行文件复制和替换
问题描述: 当我们采用 inno setup进行打包时,需要实现将安装包中的某个文件进行替换,而且我们知道在Winodws系统可以有xcopy和copy两个命令可以提供该功能;而xcopy命令进行文件复制时会有如下提示: 此时需要手动输入字…...
 
睿思BI已支持3D图形
从睿思BI旗舰版V5.3开始,系统支持如下3D图形: 3D地球 3D地图 飞线图 3D金字塔 睿思BI采用ThreeJS实现3D功能,用户也可以基于系统接口,采用ThreeJS在数据大屏中实现自己的3D图形。 系统演示地址:睿思BI旗舰版https://…...
ARCGIS---dem生成高程点
1添加DEM 2在ArcToolbox中点击“3D Analyst工具\转换\由栅格转出\栅格转多点”,调用栅格转多点工具。 3在显示的栅格转多点对话框内,输入栅格选择下载的dem数据,为了保证正常输出,输出要素类最好是默认,方法选择ZTOL…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
 
高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
 
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
 
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
 
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
 
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
