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

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

4.4.7  函数作为参数

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

 

先来看看一个例子:

func PrintFibonacci(n int, fibonacciWorker func(num int) []int) {
    if fibonacciWorker == nil {
        panic("Not assign worker")
    }
​
    result := fibonacciWorker(n)
​
    fmt.Printf("Fibonacci(%d)=%v \n", n, result)
}

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

上述代码,

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

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

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

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

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

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

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

来看看下面的代码:

type WordProcess func(input string) string
​
func filter(source string, chains []WordProcess) string {
    for _, process := range chains {
        if process != nil {
            fmt.Printf("%q =>", source)
            source = process(source)
            fmt.Printf("%q\n", source)
        }
    }
    return source
}

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

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

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

func main() {
    toUpper := func(input string) string {
        return strings.ToUpper(input)
    }
​
    toTrim := func(input string) string {
        return strings.TrimSpace(input)
    }
​
    toTrimPrefix := func(input string) string {
​
        return strings.TrimPrefix(input, "AAA")
    }
​
    chains := append([]WordProcess(nil), toUpper, toTrim, toTrimPrefix)
​
    result := filter("   aaa hello     ", chains)
    fmt.Printf("result = %v \n", result)
}

​
===== OUTPUT =====
"   aaa hello     " =>"   AAA HELLO     "
"   AAA HELLO     " =>"AAA HELLO"
"AAA HELLO" =>" HELLO"
result =  HELLO 

这个调用段的过程;

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

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

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

结束语

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

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

inthirties

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值