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. 骚包玩法1

    // 先来个简略的func work() func() int { return func() int {     return 10 + 20 }}func main() { f := work() ret := f() fmt.Println(ret)}

    输入:

    30
  2. 骚包玩法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. 骚包玩法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
  4. 对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...