• 爱上开源之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里提供路由的功能就是使用类似以上的代码进行实现的。

     

     

  • 相关阅读:
    什么是HTML?
    poll/select源码分析
    Electron+Vue+pyinstaller服务打包
    Git Commit Message规范
    使用 Eziriz .NET Reactor 对c#程序加密
    Python数据攻略-SQL和Mongodb的CRUD方法汇总
    维修派单系统好用吗?如何实现数字化后勤管理?
    吴恩达机器学习课程笔记二
    Lesson12——NumPy 字符串函数之 Part1:字符串操作函数
    基于springboot+vue的戒毒所人员管理系统毕业设计源码251514
  • 原文地址:https://blog.csdn.net/inthirties/article/details/126537907