1. 用type关键字能够定义函数类型,函数类型变量能够作为函数的参数或返回值。
package mainimport "fmt"func add(a, b int) int { return a + b}func sub(a, b int) int { return a - b}type Task func(int, int) intfunc 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 mainimport "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/Dt...