Golang-函数式编程(闭包)(二)

2014-11-23 21:44:00 · 作者: · 浏览: 42
3 4] index: 0 value: hello index: 1 value: world index: 2 value: china [2.4 6.8 4.8]

在上面的例子中,Process函数负责对切片(数组)数据进行操作,在操作切片(数组)时候,首先要做一些参数检测,例如指针是否为空、数组长度是否大于0等。这些是操作数据的公共操作。具体针对数据可以有自己特殊的操作,包括排序(升序、降序)、输出等。针对这些特殊的操作可以使用函数对象来进行封装。

再看下面的例子,这个例子没什么实际意义,只是为了说明闭包的使用方式。

package main

import (
    fmt
)

type FilterFunc func(ele interface{}) interface{}

/*
  公共操作:对数据进行特殊操作
*/
func Data(arr interface{}, filterFunc FilterFunc) interface{} {

    slice := make([]int, 0)
    array, _ := arr.([]int)

    for _, value := range array {

        integer, ok := filterFunc(value).(int)
        if ok {
            slice = append(slice, integer)
        }

    }
    return slice
}
/*
  具体操作:奇数变偶数(这里可以不使用接口类型,直接使用int类型)
*/
func EvenFilter(ele interface{}) interface{} {

    integer, ok := ele.(int)
    if ok {
        if integer%2 == 1 {
            integer = integer + 1
        }
    }
    return integer
}
/*
  具体操作:偶数变奇数(这里可以不使用接口类型,直接使用int类型)
*/
func OddFilter(ele interface{}) interface{} {

    integer, ok := ele.(int)

    if ok {
        if integer%2 != 1 {
            integer = integer + 1
        }
    }

    return integer
}

func main() {
    sliceEven := make([]int, 0)
    sliceEven = append(sliceEven, 1, 2, 3, 4, 5)
    sliceEven = Data(sliceEven, EvenFilter).([]int)
    fmt.Println(sliceEven) //[2 2 4 4 6]

    sliceOdd := make([]int, 0)
    sliceOdd = append(sliceOdd, 1, 2, 3, 4, 5)
    sliceOdd = Data(sliceOdd, OddFilter).([]int)
    fmt.Println(sliceOdd) //[1 3 3 5 5]

}

输出结果:

[2 2 4 4 6]  
[1 3 3 5 5]

Data作为公共函数,然后分别定义了两个具体的特殊函数:偶数和奇数的过滤器,定义具体的操作。

四 总结

上面例子中闭包的使用有点类似于面向对象设计模式中的模版模式,在模版模式中是在父类中定义公共的行为执行序列,然后子类通过重载父类的方法来实现特定的操作,而在Go语言中我们使用闭包实现了同样的效果。

其实理解闭包最方便的方法就是将闭包函数看成一个类,一个闭包函数调用就是实例化一个类(在Objective-c中闭包就是用类来实现的),然后就可以从类的角度看出哪些是“全局变量”,哪些是“局部变量”。例如在第一个例子中,pos和neg分别实例化了两个“闭包类”,在这个“闭包类”中有个“闭包全局变量”sum,所以这样就很好理解返回的结果了。

参考:
http://www.ibm.com/developerworks/cn/linux/l-cn-closure/index. html
http://www.cnblogs.com/kym/archive/2011/03/07/1976519.html