• 爱上开源之golang入门至实战第四章函数(Func)(七)


    爱上开源之golang入门至实战第四章函数(Func)(七)

    4.4.7  函数作为参数

    在go语言里,func本质上是一个类型关键字。 使用func来进行声明,本质上就是什么了一个func的对象。 对象名为function_name, 这个对象的类型是func。 所以在golang语言里, 在访问范围的允许情况下, 函数可以作为一个对象进行访问或者赋值给另外一个变量; 或者函数也可以作为其它函数的参数进行传递,然后在其它函数内调用执行; 就和Javascript里的callback函数一样;这个文章就来谈谈,函数作为参数在Go语言里的调用。

     

    先来看看一个例子:

    1. func PrintFibonacci(n int, fibonacciWorker func(num int) []int) {
    2. if fibonacciWorker == nil {
    3. panic("Not assign worker")
    4. }
    5. result := fibonacciWorker(n)
    6. fmt.Printf("Fibonacci(%d)=%v \n", n, result)
    7. }

    1. func FibonacciWorker(a int) (n []int) {
    2. if a <= 0 {
    3. n = append(n, 0)
    4. return
    5. }
    6. if a == 1 {
    7. n = append(FibonacciC(a-1), 1)
    8. return
    9. }
    10. n = append(FibonacciC(a - 1))
    11. n = append(n, n[len(n)-1]+n[len(n)-2])
    12. return
    13. }
    ​​
    
    1. PrintFibonacci(4, FibonacciWorker)
    2. PrintFibonacci(6, FibonacciWorker)
    3. PrintFibonacci(10, FibonacciWorker)
    4. ===== OUTPUT =====
    5. Fibonacci(4)=[0 1 1 2 3]
    6. Fibonacci(6)=[0 1 1 2 3 5 8]
    7. Fibonacci(10)=[0 1 1 2 3 5 8 13 21 34 55]

    上述代码,

    首先定义了PrintFibonacci函数,PrintFibonacci函数两个参数,

    第一个参数是整数类型,传入调用的n值,

    另一个参数fibonacciWorker是一个函数类型的参数;函数类型的参数是整数型类型,用来接收传入参数,返回一个整数类型的数组,

    在PrintFibonacci函数里, 把接收到的整数类型n,作为参数传递到fibonacciWorker这个传入的函数类型,并执行fibonacciWorker函数,返回整数型类型的数组,

    然后把返回值打印到控制台; 这样的Callback的实现模式,

    可以实现一些Java设计模式里的效果。 把具体的实现实现在具体函数里, 定义好这种函数类型的传入参数,返回值,

    然后把此类函数类型作为参数传入, 在外部调用时, 把具体的实现作为参数对这个方法进行调用,就可以达到实现和接口的隔离了。 函数也可以作为数组的元素, 把数组里的元素遍历再进行调用。

    来看看下面的代码:

    1. type WordProcess func(input string) string
    2. func filter(source string, chains []WordProcess) string {
    3. for _, process := range chains {
    4. if process != nil {
    5. fmt.Printf("%q =>", source)
    6. source = process(source)
    7. fmt.Printf("%q\n", source)
    8. }
    9. }
    10. return source
    11. }

    定义了一个WordProcess的函数类型, 传入参数字符串,返回字符串; WordProcess对传入的字符串进行字符处理。

    在第二段,定义一个filter函数,函数传入source字符串,和一个WordProcess的函数数组; 函数数组都是进行字符处理的,遍历数组取到每个WordProcess函数,并依次进行处理,然后打印转换的过程,并返回结果。

    下面我们来看看调用的代码

    1. func main() {
    2. toUpper := func(input string) string {
    3. return strings.ToUpper(input)
    4. }
    5. toTrim := func(input string) string {
    6. return strings.TrimSpace(input)
    7. }
    8. toTrimPrefix := func(input string) string {
    9. return strings.TrimPrefix(input, "AAA")
    10. }
    11. chains := append([]WordProcess(nil), toUpper, toTrim, toTrimPrefix)
    12. result := filter("   aaa hello     ", chains)
    13. fmt.Printf("result = %v \n", result)
    14. }
    15. ===== OUTPUT =====
    16. "   aaa hello     " =>"   AAA HELLO     "
    17. "   AAA HELLO     " =>"AAA HELLO"
    18. "AAA HELLO" =>" HELLO"
    19. result =  HELLO

    这个调用段的过程;

    先定义一个WordProcess的函数实现toUpper, 该实现对传入字符串进行转大写处理; 接着定义一个toTrim的函数,该函数实现对传入字符串进行去除空格处理, 最后定义一个toTrimPrefix的函数,将传入字符串前AAA字符串进行出除。

    然后通过Append函数,将三个预先定义好的WordProcess函数对象加入到chains数组里,

    最后传入字符串" aaa hello "进行filter调用, 通过filter依次调用,最后的结果就是HELLO了。

    结束语

    通过这样的方式,可以实现一些设计模式,特别是应用系统设计里,经常就有类似的代码可以发现。http里提供路由的功能就是使用类似以上的代码进行实现的。

     

     

  • 相关阅读:
    VUE3项目element-plus的icons全局引入和按需引入的打包比较
    社区治理进化史!拓世法宝化身“虚拟社工”,点亮智能社区的每一个角落
    linux 安装部署nginx
    STM32F334timer6-7
    L1-098 再进去几个人 - java
    (二)SpringCloud+Security+Oauth2 微服务初步集成
    微服务框架 SpringCloud微服务架构 3 Eureka 3.2 Eureka 原理分析
    基于JavaWeb+SpringBoot+Vue摩托车商城微信小程序系统的设计和实现
    linux-LAMP
    【COMP305 LEC 3 LEC 4】
  • 原文地址:https://blog.csdn.net/inthirties/article/details/126537907