golang不同于java和php,更多的是面向函数式编程,没有class(golang的面向对象是类型type,而不是class),

对于phper需要适应,下面总结函数的使用,以及函数作为参数在函数中的使用

1.函数是一种类型,因此可以将某个定义的函数作为参数传递给其他的函数

,譬如下面是一个函数的定义

func(r int) int {

return r

}

2.函数是可以执行的,带有返回值的,因此,可以将一个执行的函数(func(r int) int { return r}())作为参数传递给其他函数,执行函数的返回值作为参数传递给其他的函数,因此执行函数的返回值满足参数的类型即可。

譬如下面是一个函数的执行(定义后执行)

s := 1

func(r int) int {

return r

}(s)

1.一个简单的数值计算

package main

import (

"fmt"

)

func main() {

s := 1

s = s + 1

s = s * 2

fmt.Println(s)

}

输出结果:4

2.把计算改成函数,依次调用

package main

import (

"fmt"

)

func main() {

s := 1

t := addOne(s)

r := x2(t)

fmt.Println(r)

}

func addOne(s int) int {

return s + 1

}

func x2(s int) int {

return s * 2

}

输出结果:4

3.函数套用调用,也就是第一个函数的结果直接作为传输传递给另外一个函数

package main

import (

"fmt"

)

func main() {

s := 1

r := x2(addOne(s))

fmt.Println(r)

}

func addOne(s int) int {

return s + 1

}

func x2(s int) int {

return s * 2

}

输出结果:4

4.将addOne函数添加第二个参数,参数的类型是func,

从这个地方开始,phper(至少我开始学习golang的时候)会感觉有点绕

package main

import (

"fmt"

)

func main() {

s := 1

r := addOne(s, x2)

fmt.Println(r)

}

func addOne(s int, f func(t int) int) int {

s = s + 1

return f(s)

}

func x2(s int) int {

return s * 2

}

输出结果:4

函数本身也是一种类型,因此作为作为参数传递给其他的函数

func addOne(s int, f func(t int) int) int {

s = s + 1

return f(s)

}

函数作为参数类型, 需要定义函数的输入变量和返回变量,譬如上面的是func(t int) int,

只要函数这种定义的函数,就可以作为参数传递进来

对于函数x2()是满足的,因此可以作为参数传递进去,因此addOne(s, x2)可以执行,然后可以看到函数里面可以执行x2函数,也就是f(s).

5.

package main

import (

"fmt"

)

func main() {

s := 1

r := addOne(s, func(s int) int {

return s * 2

})

fmt.Println(r)

}

func addOne(s int, f func(t int) int) int {

s = s + 1

return f(s)

}

输出结果:4

去掉x2函数,直接写一个匿名函数传递

6.将执行x3()执行的返回值作为参数,传递给addOne函数

package main

import (

"fmt"

)

func main() {

s := 1

r := addOne(s, x3())

fmt.Println(r)

}

func addOne(s int, f func(t int) int) int {

s = s + 1

return f(s)

}

func x3() func(t int) int {

return func(s int) int {

return s * 2

}

}

输出结果:4

7.xx3函数的定义,由函数generateFc()返回

package main

import (

"fmt"

)

var x3 = generateFc()

func main() {

s := 1

r := addOne(s, x3())

fmt.Println(r)

}

func addOne(s int, f func(t int) int) int {

s = s + 1

return f(s)

}

func generateFc() func() func(t int) int {

return func() func(t int) int {

return func(t int) int {

return t * 2

}

}

}

输出结果:4

到这里看起来会有点小崩溃,首先func(t int) int是一个函数类型,可以作为参数,

对于func() func(t int) int 就是一个返回函数类型func(t int) int的函数类型。

因此函数generateFc()函数的返回类型是func() func(t int) int, 然后看第6部分x3的定义

func x3() func(t int) int {

return func(s int) int {

return s * 2

}

}

是不是和func() func(t int) int相符?

因此第6部分的x3是直接定义的,而第7部分的x3函数的定义,是通过执行函数generateFc()返回的。

因此你会发现:

a>函数是有类型的,只要传递参数和返回参数一致,就代表类型一样

b>函数可以直接定义,也可以通过执行一个函数得到返回值的方式定义

c>定义函数的返回值,也可以是一个函数类型,譬如上面的func() func(t int) int,他的返回值类型就是func(t int) int

8.优化第7步骤的函数

package main

import (

"fmt"

)

var x3 = generateFc()

type Ware func(t int) int

type Mdware func() Ware

func main() {

s := 1

r := addOne(s, x3())

fmt.Println(r)

}

func addOne(s int, f Ware) int {

s = s + 1

return f(s)

}

func generateFc() Mdware {

return func() Ware {

return func(t int) int {

return t * 2

}

}

}

这样易读性好很多

总结:上面这么多的写法,都可以实现1部分的执行,

在golang的包使用中起着很重要的作用,可以通过函数的妙用添加多种中间件