golang 关于函数的使用,以及函数作为参数的使用【深度解析】

Golang · Fecmall · 于 5年前 发布 · 5866 次阅读

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

共收到 0 条回复
没有找到数据。
添加回复 (需要登录)
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册
Your Site Analytics