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的包使用中起着很重要的作用,可以通过函数的妙用添加多种中间件
curring: https://blog.csdn.net/maomiaomiao/article/details/47904739