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…...

龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...

聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...