Golang函数这些神操作你知道哪些
作者:TtrOps 发布时间:2024-04-26 17:22:15
「1. 用type关键字可以定义函数类型,函数类型变量可以作为函数的参数或返回值。」
package main
import "fmt"
func add(a, b int) int {
return a + b
}
func sub(a, b int) int {
return a - b
}
type Task func(int, int) int
func exec(t Task, a, b int) int {
return t(a, b)
}
func main() {
a := exec(add, 10, 20)
fmt.Println(a)
b := exec(sub, 100, 95)
fmt.Println(b)
}
解析:type Task func(int, int) int,这句是说,使用type关键字定义1个类型为func的Task,这个func有2个int形参、1个int返回值。再看exec这个函数,它有3个形参,形参t的类型是刚定义的函数类型Task,另外两个你懂的,我就不说了。
「2. 匿名函数的玩法是真的骚,看看骚在哪里」
栗子1:匿名函数可以直接赋给变量
func main() {
var aaa = func(a, b int) int {
return a + b
}
ret := aaa(89, 78)
fmt.Println(ret)
}
输出:
167
栗子2:匿名函数作为函数入参
这个例子感觉跟刚才使用type关键字定义函数类型的例子有点相同的赶脚,仔细一看,好像也只是在使用的方式上是一样,定义函数的套路又是不同的。
func work(f func(int, int) int, a, b int) int {
return f(a, b)
}
func add(a, b int) int {
return a + b
}
func main() {
a := work(add, 100, 200)
fmt.Println(a)
}
输出:
300
解析:形参f的类型就是匿名函数,继续看func(int, int) int,这个匿名函数接收两个int形参,返回值也是int类型。另外两个形参a和b,也是int,想必你懂了,我就不废话了。
栗子3:匿名函数作为函数出参
匿名函数作为函数出参(作为函数返回值),经不断调测,有3种骚包玩法
骚包玩法1
// 先来个简单的
func work() func() int {
return func() int {
return 10 + 20
}
}
func main() {
f := work()
ret := f()
fmt.Println(ret)
}
输出:
30
骚包玩法2
// 再改造下
func work(a, b int) func() int {
return func() int {
return a + b
}
}
func main() {
f := work(500, 20)
ret := f()
fmt.Println(ret)
}
输出:
520
骚包玩法3
// 再次改造
func work() func(int, int) int {
return func(a, b int) int {
return a + b
}
}
func main() {
f := work()
ret := f(600, 50)
fmt.Println(ret)
}
输出:
650
对3种骚包玩法的简单解析:
再这里就解析一下第3种玩法,能搞懂这个玩法,前面2个玩法,你就自然懂了。work函数没有入参,但是有出参(也可以说是返回值),出参是匿名函数func(int, int) int,这个定义在返回值里的匿名函数有2个int类型的形参(入参)和1个int类型的返回值。再看看函数体内部,没干很复杂活儿,而是直接return了匿名函数,函数体里的这个匿名函数是和定义在返回值里的类型保持一致的,也是接收了2个int的形参a和b,返回值也是int,啥也没干,就做了个相加。好郁闷!不知道你看懂了没?再看看是如何使用work函数的,关键点就在这里,调用work()赋给了变量f,这时候,f它就是一个函数了,再调用f(600, 50),想必你已经知道了为啥要传入2个int值,这下搞定!不知道把你绕晕没,这玩法确实很骚。
「3. 匿名函数和延迟调用」
延迟调用的规则是:按照「先进后出」的顺序,也就是说函数返回前是会被执行的,而且是按照先进后出的顺序。如何起到延迟的效果,是需要注册的,可通过defer关键字进行注册。那么什么场景下需要用到延迟调用呢?比如常见的场景:当一个函数被即将执行完后,也就是完成任务的最后一刻,需要回收和释放某些资源。
延迟调用的机制可以配合匿名函数来使用,这样就可以让匿名函数被直接调用,只能说是真的骚。
先看个小栗子:
package main
import "fmt"
func work() bool {
fmt.Println("函数开始工作...")
defer func() {
fmt.Println("回收相关资源工作开始!")
}()
defer func() {
fmt.Println("清理工作开始!")
}()
fmt.Println("函数正在工作...")
fmt.Println("函数工作完毕...")
return true
}
func main() {
status := work()
fmt.Println(status)
}
输出:
函数开始工作...
函数正在工作...
函数工作完毕...
清理工作开始!
回收相关资源工作开始!
true
在上面的栗子中,定义了个work函数,先看看输出的结果,感受下。在work函数中,注册了两个延迟调用,work函数从开始->正在->完毕,结束后才执行defer注册的匿名函数,这里要着重注意延迟调用规则:「先进后出」,也就是先注册后执行。“回收相关资源工作”是先注册的,他的执行顺序排在了“清理工作”的后面。感受到了吗?
最后说明一下:defer关键字让匿名函数实现了可直接调用,那么使用defer注册延迟调用时要注意,defer关键字的后面一定是要函数或方法的调用,不能直接写语句哦。
来源:https://mp.weixin.qq.com/s/DtSWp-APaAPmTG1mjAMRQQ


猜你喜欢
- 废话不多说,直接开干!抖音字符视频在今年火过一段时间。反正我是始终忘不了那段刘耕宏老师本草纲目的音乐…这一次自己也来实
- 在编程时你一定碰到过时间触发的事件,在VB中有timer控件,而ASP中没有,假如你要不停地查询数据库来等待一个返回结果的话,我想你一定知道
- 本文实例讲述了Python3.5集合及其常见运算。分享给大家供大家参考,具体如下:1、集合的定义:集合是一个无序的、无重复的数据的数据组合。
- 一个事务是一个连续的一组数据库操作,就好像它是一个单一的工作单元进行。换言之,永远不会是完整的事务,除非该组内的每个单独的操作是成功的。如果
- 支持lrc歌词,IE only 代码未加密且有详细注释,希望对做音乐页面的朋友有帮助。 如果大家还有什么好多播放器,告诉我,我好参
- 要实现的SQL查询很原始:要求从第一个表进行查询得到第二个表格式的数据,上网查询之后竟然能写出下面的SQL:代码如下:select * fr
- python的数据类型有:数字(int)、浮点(float)、字符串(str),列表(list)、元组(tuple)、字典(dict)、集合
- 第三方库 binarytree其使用环境、安装方法及二叉树的相关知识,请见:《Python 初识二叉树,新手也秒懂!》不能导入的请安装:pi
- 目录全局中间件应用中间件路由中间件控制器中间件中间件传参6.0中间件分为系统中间件和应用中间件,系统中间件为核心框架内置的中间件,应用中间件
- 最近在实习,boss给布置了一个python的小任务,学习过程中发现copy()和deepcopy()这对好 * 实在是有点过分,搞的博主就有
- 国庆期间准备写三篇博客,介绍和总结下接口测试,由于国庆期间带娃,没有按照计划完成,今天才完成第二篇,惭愧惭愧。这里我第一篇博客的地址:htt
- 用 xlrd 模块读取 Excelxlrd 安装cmd 中输入pip install xlrd 即可安装 xlrd 模块若失败请自行百度”p
- 在mysql中limit可以实现快速分页,但是如果数据到了几百万时我们的limit必须优化才能有效的合理的实现分页了,否则可能卡死你的服务器
- 前言之前看到一个有意思的开源项目,主要是可以将一张照片变成卡通漫画的风格。下面给大家放几张官方给出的部分效果图。看到这个效果图,还是非常经验
- 怎样编制留言簿程序呢?留言簿程序并不难,有很多选择可以实现,如CGI程序等等。本文介绍怎样用JavaScript编制留言簿程序,下面是一个完
- 1、string-->numberstring类型 *1 即可变成 number类型2
- 本文实例汇总了常用的JavaScript弹出窗口方法,供大家对比参考,希望能对大家有所帮助。详细方法如下:1.无提示刷新网页:大家有没有发现
- 代码如下Control:from django.conf.urls import patterns, include, urlfrom dj
- 在正式的生产环境中,我们常常会需要监控服务器的状态,以保证公司整个业务的正常运转,常常我们会用到像nagios、zabbix这类工具进行实时
- 很多时候我们写的程序,会花上一分钟甚至几分钟时间。为了使软件使用者能够耐心的等待程序的执行,我们经常会希望有一个进度条来表示程序执行的状态。