提供一种非常 “绕” 的思路,实现一下 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{}) }
type HandlerFunc func(k, v interface{}) func (f HandlerFunc) Do(k, v interface{}) { f(k, v) }
func Each(m map[interface{}]interface{}, h Handler) { if m != nil && len(m) > 0 { for k, v := range m { h.Do(k, v) } } }
func EachFunc(m map[interface{}]interface{}, f func(k, v interface{})) { Each(m, HandlerFunc(f)) } 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 函数类型接口, 坑