接口型函数,指的是用函数实现接口,这样调用的时候就会非常简便,我称这种函数为接口型函数。这种方式使用于只有一个函数的接口。
我们以迭代一个map为例,演示这一技巧,这种方式有点类似于goporxy中Map的each一样,也是Gradle里的闭包。
原始接口实现
//handle接口
type Handle interface {
Do(k,v interface{})
}
//Each函数
func Each(m map[interface{}] interface{},h Handle){
if m != nil && len(m) > 0 {
for k,v range m {
h.Do(k,v)
}
}
}
首先定义一个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的实现,我们添加代码如下: