接口型函数,指的是用函数实现接口,这样调用的时候就会非常简便,我称这种函数为接口型函数。这种方式使用于只有一个函数的接口。
    我们以迭代一个map为例,演示这一技巧,这种方式有点类似于goporxy中Map的each一样,也是Gradle里的闭包。

    原始接口实现

    1. //handle接口
    2. type Handle interface {
    3. Do(k,v interface{})
    4. }
    5. //Each函数
    6. func Each(m map[interface{}] interface{},h Handle){
    7. if m != nil && len(m) > 0 {
    8. for k,v range m {
    9. h.Do(k,v)
    10. }
    11. }
    12. }

    首先定义一个Handle接口,只有一个Do方法,接收k,v两个参数,这就是一个接口了,我们后面会实现它,具体做什么由我们的实现决定。

    然后我们定义看一个Each函数,这个函数的功能,就是迭代传递过来的map参数,然后把map的每个key和value值传递给Handle的Do方法,去做具体的事情。
    可以是输出,也可以是计算,具体由Handle的实现来决定,这也是面向接口编程。

    现在我们就以新学期开学,大家来自我介绍为例,演示使用我们刚刚定义的Each方法和Handle接口。这里我们假设有三个学生,分别为:张三、李四和王五,
    他们每个人都要介绍自己的名字和年龄。

    type welcome string
    
    func (w welcome) Do(k,v interface{}){
        fmt.Prinf("%s,我叫%是,今年%d岁\n",k,v)
    }
    
    func main(){
        persons := make(map[interface{}]interface{})
        persons["张三"] = 20 
        persons["李四"] = 23
        persons["王五"] = 26
    
        var w welcome = "大家好"
        Each(persons,w)
    }
    

    以上实现,我们定义了一个map来存储学生们,map的key是学生的名字,value是该学生的年龄。welcome是我们新定义的类型,对应基本类型strring,该welcome实现了Handle接口,打印出自我介绍。

    接口型函数出场

    以上实现,主要有两点不好:
    因为必须要实现Hanler接口,Do这个方法名不能修改,不能定义一个更有意义的名字。
    必须要重新定义一个类型,才可以实现Handle接口,才能使用Each函数。

    首先我们先解决第一个问题,根据我们具体要做的事情定义一个更有意义的方法名,比如例子中是自我介绍,那么使用seIfInfo要比Do这个·干巴巴的方法要好很多。
    如果调用者改了方法名,那么就不能实现Handle接口,我们还要使用Each方法怎么办?那就是由Each函数分负责提供Handle的实现,我们添加代码如下: