当前位置: 首页 > news >正文

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。让我们来理解这意味着什么。

变量ab在17, 18行号中声明。 是闭包,它们与自己的值 绑定t

我们首先a使用World参数进行调用。a现在的版本的值t变为Hello World

在20 行号中。我们bEveryone参数调用。由于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)以「一套系统,天生全能」为准则&#xff0…...

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每日刷题&#xff08;二十&#xff09; 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 运行时进行文件复制和替换

问题描述&#xff1a; 当我们采用 inno setup进行打包时&#xff0c;需要实现将安装包中的某个文件进行替换&#xff0c;而且我们知道在Winodws系统可以有xcopy和copy两个命令可以提供该功能&#xff1b;而xcopy命令进行文件复制时会有如下提示&#xff1a; 此时需要手动输入字…...

睿思BI已支持3D图形

从睿思BI旗舰版V5.3开始&#xff0c;系统支持如下3D图形&#xff1a; 3D地球 3D地图 飞线图 3D金字塔 睿思BI采用ThreeJS实现3D功能&#xff0c;用户也可以基于系统接口&#xff0c;采用ThreeJS在数据大屏中实现自己的3D图形。 系统演示地址&#xff1a;睿思BI旗舰版https://…...

ARCGIS---dem生成高程点

1添加DEM 2在ArcToolbox中点击“3D Analyst工具\转换\由栅格转出\栅格转多点”&#xff0c;调用栅格转多点工具。 3在显示的栅格转多点对话框内&#xff0c;输入栅格选择下载的dem数据&#xff0c;为了保证正常输出&#xff0c;输出要素类最好是默认&#xff0c;方法选择ZTOL…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...