Golang: 函数类型实现接口封装问题(11)

提供一种非常 “绕” 的思路,实现一下 C 语言那种函数指针的灵活。

专栏的介绍可以参考 《GotchaGolang专栏》,代码可以看《宝库-Gotcha》

函数类型实现接口提供了一种非常好的思路,比如 http.Handler 就是这么实现的:

1
2
3
4
5
6
7
8
9
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
func Handle(pattern string, handler Handler) {
DefaultServeMux.Handle(pattern, handler)
}
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
DefaultServeMux.HandleFunc(pattern, handler)
}

然后我们平常调用的时候,传递的 Handler 其实都是函数类型,也就是说, Handler 接口可以由函数类型实现。

下面代码的脉络或许封装过多,但是如果把握 函数作为一种类型,实现接口其实还好:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package main
import (
"fmt"
)

//接口
type Handler interface {
Do(k, v interface{})
}

//函数类型实现接口 Handler
type HandlerFunc func(k, v interface{})
func (f HandlerFunc) Do(k, v interface{}) {
f(k, v)
}

//这里 Handler 可以接收 HandlerFunc 类型
func Each(m map[interface{}]interface{}, h Handler) {
if m != nil && len(m) > 0 {
for k, v := range m {
h.Do(k, v) //h(k, v) --- selfInfo(k, v) 注意
}
}
}

func EachFunc(m map[interface{}]interface{}, f func(k, v interface{})) {
Each(m, HandlerFunc(f)) //selfInfo 做了一下转换 HandlerFunc 类型(子类、实现了 Handler 接口)。
}
func selfInfo(k, v interface{}) {
fmt.Printf("大家好,我叫%s,今年%d岁\n", k, v)
}
func main() {
persons := make(map[interface{}]interface{})
persons["张三"] = 20
persons["李四"] = 23
persons["王五"] = 26
EachFunc(persons, selfInfo)
}

运行结果:

1
2
3
大家好,我叫张三,今年20岁
大家好,我叫李四,今年23岁
大家好,我叫王五,今年26岁

全部的精妙,都是从 type HandlerFunc func(k, v interface{}) 类型开始。

不过也应该封装过多,造成调用层次过深,了解即可。原文参考 飞雪博客-接口型函数


Merlin 2018.3 函数类型接口, 坑

文章目录
|