如何在手机上做自己的网站/链接平台
go 语言函数
- go 函数
- 函数定义
- Go函数的特点如下
- 函数作为参数
- 可变参数
- 相同类型可变参数
- 不同类型可变参数
- return语句
- 作用概述
- 空的return语句
- 空白标识符
- 多个返回值
- 命名返回值
- defer 语句
- 作用
- 引申出来的面试题for defer
- 下面是一个使用`defer`的示例代码
- 输出结果
- 匿名函数
- 定义匿名函数
- 使用匿名函数
- 作用
- 使用注意事项
- 闭包
- 闭包定义
- 闭包的特点:
- 闭包的使用场景:
- 以下是一个使用闭包的示例代码:
go 函数
函数定义
在Go中,函数是一种基本的代码块,用于执行特定的任务。函数在Go中被定义为一个代码块,具有名称和一些参数,可以接受并返回值。函数定义如下:
func function_name(parameter_name type) return_type {// 函数体return value
}
其中,func
是关键字,function_name
是函数的名称,parameter_name
是参数的名称,type
是参数的数据类型,return_type
是函数的返回类型,value
是函数返回的值。
Go函数的特点如下
- 支持多返回值:Go语言的函数可以返回多个值,这样可以方便地返回多个计算结果或者同时处理多个返回值。
- 命名返回值:可以在函数定义时给返回值命名,使得函数内部可以直接使用这些变量,并且在函数结束时,可以通过简单的
return
语句来返回这些已命名的值。 - 支持可变参数:Go语言允许函数接受可变数量的参数。通过使用
...
语法,函数可以接受任意数量的相同类型参数。 - 支持defer语句:
defer
语句用于在函数执行完毕后,延迟执行指定的代码块。这在需要在函数返回前执行一些清理或资源释放操作时非常有用。 - 可以有多个
return
语句,但是只是会执行其中一个,执行后就会返回。 - 递归支持:Go语言支持递归函数,可以在函数体内调用自己,用于解决一些需要重复执行的问题。
- 支持错误处理:函数可以返回错误信息,用于指示函数执行中是否发生错误。Go鼓励使用多返回值来返回函数执行状态以及错误信息,以实现更可靠的错误处理机制。
- 函数作为一等公民:在Go语言中,函数可以像其他变量一样进行传递、赋值和作为参数传递给其他函数,作为返回值,这使得函数在Go中具有更强大的表现力和灵活性。
- 支持匿名函数和闭包:Go语言支持在函数内部定义匿名函数,并且这些函数可以捕获外部函数的局部变量,形成闭包。匿名函数是指没有名称的函数,可以直接将其赋值给变量或直接调用。
- 支持函数闭包:在Go中,可以在一个函数中定义另一个函数,内部函数可以访问外部函数的局部变量。这种特性被称为函数闭包,它可以用于实现一些更为复杂的逻辑和功能。闭包是指一个函数可以访问其外部作用域中的变量,即使该变量在函数外部也可以访问。
函数作为参数
在Go语言中,函数是一等公民,这意味着函数可以像其他变量一样被传递给其他函数,作为参数传递给其他函数。这样的特性使得函数更加灵活和强大,可以实现更为复杂的逻辑和功能。
在Go中,函数可以被声明为类型,例如:
type MyFunction func(int, int) int
上面的代码中,MyFunction
被声明为一个函数类型,它接受两个int
类型的参数并返回一个int
类型的值。
然后,我们可以在其他函数中使用这个函数类型作为参数,例如:
func calculate(a, b int, op MyFunction) int {return op(a, b)
}
在这个例子中,calculate
函数接受三个参数:两个int
类型的数值a
和b
,还有一个函数类型op
。该函数类型op
的签名必须和MyFunction
相同,接受两个int
类型参数并返回一个int
类型值。函数calculate
会将a
和b
作为参数传递给op
函数,并返回op
函数的结果。
使用示例:
func add(a, b int) int {return a + b
}func multiply(a, b int) int {return a * b
}func main() {result1 := calculate(2, 3, add) // 使用add函数进行加法运算,结果为5result2 := calculate(2, 3, multiply) // 使用multiply函数进行乘法运算,结果为6fmt.Println(result1, result2)
}
在上面的示例中,我们声明了add
和multiply
两个函数,并在main
函数中使用calculate
函数来执行加法和乘法运算,通过将不同的函数作为参数传递给calculate
函数,我们可以轻松地在calculate
函数中实现不同的操作,增加了代码的灵活性和可复用性。
函数作为参数的特性在Go语言中非常常用,它允许我们以一种通用的方式编写函数,以便在不同的场景下重用这些函数,并通过传递不同的函数作为参数来实现不同的功能。这种编程风格在编写高阶函数和实现回调机制时特别有用
可变参数
相同类型可变参数
在Go中,可以使用可变参数函数来接受不定数量的参数。这在需要传递不同数量参数的情况下非常有用。例如,fmt.Println() 函数可以接受不定数量的参数并将它们打印到控制台上。在Go中,使用可变参数函数时,需要在函数签名中指定 “…” 符号,表示参数数量不定。
下面是一个示例,演示了如何在Go中使用可变参数函数:
func sum(nums ...int) int {total := 0for _, num := range nums {total += num}return total
}func main() {fmt.Println(sum(1, 2, 3)) // 输出:6fmt.Println(sum(1, 2, 3, 4)) // 输出:10
}
在上面的代码中,函数 sum
声明了一个可变参数 nums
,表示可以接受任意数量的整数参数。在函数体内,我们使用 range 遍历了传入的参数,将它们相加后返回总和。
我们可以通过传递任意数量的参数来调用 sum
函数,示例中分别传递了 3 个参数和 4 个参数。函数会将它们全部相加并返回结果。
不同类型可变参数
在 Go 语言中,是可以传递多个不同类型的可变参数的。可以使用 interface{}
类型作为可变参数的类型,它可以表示任意类型的值。
下面是一个例子,展示了如何使用 interface{}
类型作为可变参数的类型,以便传递多个不同类型的值:
func printValues(values ...interface{}) {for _, value := range values {fmt.Println(value)}
}func main() {printValues(1, "two", true)
}
在上面的例子中,printValues
函数的可变参数类型被定义为 interface{}
,因此可以接受多个不同类型的值。在 main
函数中,我们传递了三个不同类型的值:整数、字符串和布尔值。在 printValues
函数中,我们使用 range
循环遍历所有传递进来的参数,并使用 fmt.Println
打印每个值。这样,我们就可以打印多个不同类型的值了。
return语句
作用概述
在Go中,return
语句用于从函数中返回值并停止函数执行,并把代码的执行权返回给调用者。对于无返回值的函数,函数体末尾的return语句可以直接省略。return
语句可以放在函数中的任何位置,并且可以返回零个、一个或多个值。
空的return语句
在无返回值函数(void函数)中,可以使用空的return语句来显式地结束函数的执行。
func doSomething() {// 一些操作return // 空的return语句表示函数执行结束
}
空白标识符
如果函数有命名返回值,但不打算在函数体中使用它们,可以使用下划线 _
作为空白标识符表示忽略这些返回值。
func divide(a, b float64) (result float64, err error) {// ...if b == 0 {err = fmt.Errorf("cannot divide by zero")return 0, err // 只返回错误,忽略result的返回值}// ...return // 只返回result,忽略err的返回值
}
多个返回值
在函数中,可以返回多个值,例如:
func calculate(a, b int) (int, int, int, float64) {sum := a + bdiff := a - bproduct := a * bquotient := float64(a) / float64(b)return sum, diff, product, quotient
}
在上面的例子中,calculate
函数返回四个值,它们是a
和b
的和、差、积和商。
命名返回值
在Go中,也可以在函数签名中为返回值指定名称,这些名称被视为函数的局部变量,在函数体中可以直接使用。如果在函数体中没有显式使用return语句,则返回值会自动被返回。例如:
func add(a, b int) (sum int) {sum = a + breturn
}
在上面的例子中,函数返回类型为int
,并且返回值被命名为sum
。在函数体中,sum
被计算为a
和b
的和,并通过不带参数的return
语句返回。
defer 语句
作用
- 在Go语言中,
defer
语句用于延迟执行一个函数调用,通常用于确保在函数执行完毕前进行一些清理操作。defer
语句会将函数调用推迟到包含它的函数即将返回之前执行,无论函数是正常返回还是发生了异常 - 在实际应用中,要确保在执行函数的过程中遇到错误时及时处理一些必要的事情,比如关闭连接、关闭文件等。通常情况下可以使用
defer
关键字实现这些功能。 defer
关键字用于释放资源,会在函数返回之前调用,即便函数崩溃也会在结束之前调用defer
。- 一个函数内可以有多个
defer
,在调用时按照栈的方式先进后出,即写在前面的后调用。
引申出来的面试题for defer
下面是一个使用defer
的示例代码
package mainimport "fmt"func main() {for i := 1; i <= 5; i++ {defer fmt.Println(i)}fmt.Println("Done")
}
输出结果
Done
5
4
3
2
1
在这个示例中,我们使用了一个for
循环,并在每次循环迭代时使用defer
语句延迟打印变量i
的值。当程序执行到defer fmt.Println(i)
时,不会立即执行该语句,而是在包含它的函数即将返回之前才执行。因此,打印的结果是逆序的。
需要注意的是,defer
语句是按照后进先出(LIFO)的顺序执行的。在示例代码中,我们使用了一个for
循环,每次循环迭代都会推迟一个新的defer
语句,所以在函数返回前,defer
语句会按照逆序执行。
总结起来,使用defer
语句可以确保在函数返回前执行一些必要的清理操作,而无需在每个可能的返回点都进行显式的调用。在使用defer
语句时需要注意推迟的函数调用的执行顺序,以及可能产生的副作用。
匿名函数
匿名函数是一种在Go语言中可以直接定义且没有函数名的函数。它是一种特殊类型的函数,可以在定义的地方直接使用,而不需要为其分配一个名字。匿名函数在Go中非常常用,特别是在需要传递函数作为参数、或者在闭包中使用时。
定义匿名函数
在Go语言中,定义匿名函数的一般形式为:
func(parameters) returnType {// function body
}
其中,parameters
表示函数的参数列表,returnType
表示函数的返回类型(可以省略),function body
表示函数体。
使用匿名函数
匿名函数可以直接在代码中使用,例如:
func main() {// 使用匿名函数计算两个数的和sum := func(a, b int) int {return a + b}(2, 3) // 调用匿名函数并传入参数2和3fmt.Println(sum) // 输出结果:5
}
在上面的例子中,我们定义了一个匿名函数并直接在代码中调用它,计算两个数的和并将结果存储在变量sum
中。
作用
匿名函数主要有两个作用:
- 作为参数传递:可以将匿名函数作为参数传递给其他函数,从而实现在函数中传递逻辑或行为。
- 闭包:匿名函数可以捕获外部函数中的变量,形成闭包。这意味着匿名函数可以访问外部函数的局部变量,即使外部函数已经执行完毕。
使用注意事项
在使用匿名函数时,需要注意以下几点:
- 调用匿名函数:定义匿名函数后,需要在定义后使用小括号
()
调用函数并传入参数(如果有参数的话)。 - 作为参数传递:可以将匿名函数作为参数传递给其他函数,以便在函数中执行匿名函数的逻辑。
- 闭包问题:在使用匿名函数时,尤其是在闭包中使用时,要注意外部变量的生命周期,确保不会出现意外的结果。
- 函数类型:匿名函数可以赋值给函数类型的变量,以便在其他地方使用。
- 变量作用域:在匿名函数中可以访问外部函数的局部变量,但要注意变量作用域的问题。
总结:匿名函数是Go语言中的一种强大特性,它可以简化代码并增加程序的灵活性。通过匿名函数,我们可以更加方便地编写高阶函数、实现闭包和实现回调机制,让我们的代码更加优雅和易于维护。但在使用匿名函数时,要特别注意变量作用域和闭包问题,避免出现不必要的错误。
闭包
闭包定义
闭包(Closure)是一个函数值(Function Value),它包含了函数的代码以及该函数的引用环境(变量)。
具体来说,闭包是指在函数内部定义的函数,这个内部函数可以访问其外部函数的局部变量,并且在外部函数的生命周期内都保持有效。闭包可以捕获和存储其外部函数的局部变量,并使得这些变量在内部函数被调用时保持状态。
闭包的特点:
- 内部函数可以访问外部函数的局部变量。
- 外部函数的局部变量被内部函数引用后,其生命周期得到延长,直到内部函数不再被引用时才会被销毁。
- 外部函数返回的是内部函数的函数值。
- 同一个闭包函数中的变量的生命周期是整个闭包函数的生命周期
闭包的使用场景:
- 常用于实现一些类似于对象的功能,隐藏了内部的状态信息,只提供对外暴露的方法。
- 用于实现回调机制,将函数作为参数传递给其他函数。
以下是一个使用闭包的示例代码:
package mainimport "fmt"func adder() func(int) int {sum := 0 // 外部函数的局部变量return func(x int) int {sum += x // 内部函数访问外部函数的局部变量return sum}
}func main() {// 创建一个闭包函数,该函数可以累加传入的参数myAdder := adder()// 调用闭包函数,实现累加fmt.Println(myAdder(1)) // 输出结果:1fmt.Println(myAdder(2)) // 输出结果:3fmt.Println(myAdder(3)) // 输出结果:6
}
在上面的例子中,我们定义了一个外部函数adder
,它返回了一个闭包函数。闭包函数中引用了外部函数的局部变量sum
,并可以持续地累加传入的参数。每次调用myAdder
函数,都会保留之前的sum
值,并在原来的基础上继续累加。这就是闭包的特性,使得局部变量sum
的生命周期得到了延长,并在多次调用中保持了状态。
闭包在Go语言中是一种非常有用且强大的特性,可以用于简化代码、实现高阶函数和实现回调机制。但在使用闭包时,要注意不要滥用闭包,避免造成资源泄漏或不必要的性能损失。
相关文章:

go 函数
go 语言函数 go 函数函数定义Go函数的特点如下函数作为参数可变参数相同类型可变参数不同类型可变参数 return语句作用概述空的return语句空白标识符多个返回值命名返回值 defer 语句作用引申出来的面试题for defer下面是一个使用defer的示例代码输出结果 匿名函数定义匿名函数…...

python之正则表达式
目录 正则表达式 python正则表达式方法 match search findall finditer compile 元字符匹配 元字符 量词 贪婪匹配和惰性匹配 正则表达式的group 语法 案例 正则表达式 正则表达式又称规则表达式,是使用单个字符串来描述、匹配某个句法规则的字符串…...

【LeetCode每日一题】——219.存在重复元素II
文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 哈希表 二【题目难度】 简单 三【题目编号】 219.存在重复元素II 四【题目描述】 给你一个…...

篇六:适配器模式:让不兼容变兼容
篇六:“适配器模式:让不兼容变兼容” 开始本篇文章之前先推荐一个好用的学习工具,AIRIght,借助于AI助手工具,学习事半功倍。欢迎访问:http://airight.fun/ 另外有2本不错的关于设计模式的资料,…...

【云原生】Docker-compose中所有模块学习
compose模块 模板文件是使用 Compose 的核心,涉及到的指令关键字也比较多。但大家不用担心,这里面大部分指令跟 docker run 相关参数的含义都是类似的。 默认的模板文件名称为 docker-compose.yml,格式为 YAML 格式。 version: "3&quo…...

广义积分练习
前置知识 无穷限积分瑕积分 练习 计算 ∫ 0 ∞ 1 x ( 1 x ) d x \int_0^{\infty}\dfrac{1}{\sqrt x(1x)}dx ∫0∞x (1x)1dx 解: x 0 \qquad x0 x0为瑕点 \qquad 原式 lim a → 0 lim b → ∞ ∫ a b 1 x ( 1 x ) d x lim a → 0 lim …...

element-ui树形表格,左边勾选,右边显示选中的数据-功能(如动图)
功能如图 功能需求 表格树形表格勾选数据,右边显示对应勾选的数据内容,选中客户,自动勾选所有的店铺(子级),选中其中一个店铺,自动勾选上客户(父级),同时会存在只有客户(下面没有子级的情况&am…...

Android数字价格变化的动画效果的简单实现
原理:使用ValueAnimator属性动画类实现,它通过值的改变手动设置对象的属性值来实现动画效果。直接贴代码: public static void doNumberAnim(TextView tvPrice, float startNumber, float endNumber) {ValueAnimator animator ValueAnimato…...

Win10无法投影关闭3D模式
Win10不小心开启了3D模式,插上投影仪就一闪一闪的,无法正投影 解决办法: 1. 打开注册表工具regedit,删除以下注册表,重启电脑 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GraphicsDrivers\Configurat…...

FFmpeg 编码详细流程
介绍 FFmpeg的 libavcodec 模块完成音视频多媒体的编解码模块。FFmpeg 本身不具有音视频编码的功能和底层能力,只是对各类第三方的编码器API 进行封装调用。老版本的 FFmpeg 将avcodec_encode_video2()作为视频的解码函数 API,将avcodec_encode_audio2(…...

05如何做微服务架构设计
一句话导读 微服务架构设计方法有:领域驱动设计DDD(Domain-Driven-Design)、12因素应用(12-Factor App)、事件驱动架构EDA(Event-Driven Architecture)等等,但是他们都必须遵守微服务…...

安卓开发问题记录:需要常量表达式
问题原因 写代码过程中爆出这个错误:需要常量表达式,定位到switch。 解决方法:把switch case,改成if else 错误源代码: public void onClick(View view) {switch (view.getId()) {case R.id.iv_code:RxCaptcha.build(…...

回归预测 | MATLAB实现基于SVM-RFE-BP支持向量机递归特征消除特征选择算法结合BP神经网络的多输入单输出回归预测
回归预测 | MATLAB实现基于SVM-RFE-BP支持向量机递归特征消除特征选择算法结合BP神经网络的多输入单输出回归预测 目录 回归预测 | MATLAB实现基于SVM-RFE-BP支持向量机递归特征消除特征选择算法结合BP神经网络的多输入单输出回归预测预测效果基本介绍研究内容程序设计参考资料…...

配置root账户ssh免密登录并使用docker-machine构建docker服务
简介 Docker Machine是一种可以在多种平台上快速安装和维护docker运行环境,并支持多种平台,让用户可以在很短时间内在本地或云环境中搭建一套docker主机集群的工具。 使用docker-machine命令,可以启动、审查、停止、重启托管的docker 也可以…...

【力扣周赛】第357场周赛
【力扣周赛】第357场周赛 2810. 故障键盘题目描述解题思路 2811. 判断是否能拆分数组题目描述解题思路 2810. 故障键盘 题目描述 描述:你的笔记本键盘存在故障,每当你在上面输入字符 ‘i’ 时,它会反转你所写的字符串。而输入其他字符则可以…...

多线程案例(4)-线程池
文章目录 多线程案例四四、线程池 大家好,我是晓星航。今天为大家带来的是 多线程案例-线程池 相关的讲解!😀 多线程案例四 四、线程池 线程池是什么 虽然创建线程 / 销毁线程 的开销 想象这么一个场景: 在学校附近新开了一家…...

【数据结构OJ题】轮转数组
原题链接:https://leetcode.cn/problems/rotate-array/ 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 1. 方法一:暴力求解,将数组的第一个元素用临时变量tmp存起来,再将数组其他元素往右挪动一步&…...

现代C++中的从头开始深度学习:【4/8】梯度下降
一、说明 在本系列中,我们将学习如何仅使用普通和现代C编写必须知道的深度学习算法,例如卷积、反向传播、激活函数、优化器、深度神经网络等。 在这个故事中,我们将通过引入梯度下降算法来介绍数据中 2D 卷积核的拟合。我们将使用卷积和上一个…...

Yolov5缺陷检测/目标检测 Jetson nx部署Triton server
使用AI目标检测进行缺陷检测时,部署到Jetson上即小巧算力还高,将训练好的模型转为tensorRT再部署到Jetson 上供http或GRPC调用。1 Jetson nx 刷机 找个ubuntu 系统NVIDIA官网下载安装Jetson 的sdkmanager一步步刷机即可。 本文刷的是JetPack 5.1, 其中包…...

MobaXterm 中文乱码, 及pojie
中文解决方法: 把“连字”去掉! MobaXterm网页,可以生成一个授权文件Custom.mxtpro。放在安装目录就可以了 MobaXterm Keygen (husbin.top)http://b70.husbin.top:5000/...

java: 程序包sun.misc不存在
启动失败,rebuild时也报错:java: 程序包sun.misc不存在 问题出在JDK版本上,这个包在JDK9的时候已经被弃用了,这里改回JDK8即可 步骤如下:...

WSL2Linux 子系统(五)
WLS2Linux 子系统编译 Android 上一篇文章中讲解 《WLS2Linux 子系统迁移/恢复》,从C盘迁移到D盘。既可以防止C盘爆红,又可以释放磁盘空间。有更大存储空间意味大有可为,比如说编译Android系统。本文则以开源 firefly Android10代码为例简单…...

java 企业工程管理系统软件源码 自主研发 工程行业适用 em
工程项目管理软件(工程项目管理系统)对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营,全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#…...
IPO观察丨困于门店扩张的KK集团,还能讲好增长故事吗?
KK集团发起了其IPO之路上的第三次冲击。 近日,KK集团更新了招股书,继续推进港交所上市进程,此前两次上市搁置后终于有了新动向。从更新内容来看,KK集团招股书披露了公司截至2023年一季度的最新业绩,交出一份不错的“成…...

【iOS】RunLoop
前言-什么是RunLoop? 什么是RunLoop? 跑圈?字面上理解确实是这样的。 Apple官方文档这样解释RunLoop RunLoop是与线程息息相关的基本结构的一部分。RunLoop是一个调度任务和处理任务的事件循环。RunLoop的目的是为了在有工作的时候让线程忙起来&#…...

数据包传输方式:单播、多播、广播、组播、泛播
数据包传输方式 单播、多播、广播、组播、泛播 网络中假设X代表所有的机器,Y代表X中的一部分机器,Z代表一组机器,1代表一台机器,那么 1:1 那就是单播;1:Y 那就是多播;1࿱…...

WebRTC基础知识
文章目录 基础概念NAT (Network Address Translation) 打洞STUN(Session Traversal Utilities for NAT)基于STUN协议的DDoS反射攻击 # TODO TURN(Traversal Using Relays around NAT)ICE(Interactive Connectivity Est…...

积累常见的有针对性的python面试题---python面试题001
1.考点列表的.remove方法的参数是传入的对应的元素的值,而不是下标 然后再看remove这里,注意这个是,删除写的那个值,比如这里写3,就是删除3, 而不是下标. remove不是下标删除,而是内容删除. 2.元组操作,元组不支持修改,某个下标的内容 可以问他如何修改元组的某个元素 3.…...

在springboot使用websocket时mapper无法注入
直接上代码 package cn.ujoined.combined.utils;import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Componen…...

前端加密与解密的几种方式
1.base64加密方式 1. base64是什么? Base64,顾名思义,就是包括小写字母a-z、大写字母A-Z、数字0-9、符号""、"/"一共64个字符的字符集,(另加一个“”,实际是65个字符,至于…...