Go从入门到精通——函数类型实现接口(把函数作为接口来调用)
函数类型实现接口(把函数作为接口来调用)
函数和其他类型一样都属于 "一等公民",其他类型能够实现接口,函数也可以。
我们对比下结构体和函数实现接口的过程。
先实现一个接口:
1 2 3 4 5 | //调用器接口 type Invoker interface { //需要实现一个 Call() 方法 Call( interface ()) } |
这个接口需要实现 Call() 方法,调用时会传入一个 interface{} 类型的变量,这种类型的变量表示任意类型的值。
1、结构体实现接口
结构体实现 Invoker 接口的代码如下:
1 2 3 4 5 6 7 8 | //结构体类型 type Struct struct { } //实现 Invoker 的 Call func (s *Struct) Call(p interface {}){ fmt.Println( "from struct" , p) } |
代码说明如下:
- 第 2 行,定义结构体,该例子中的结构体无须任何成员,主要展示实现 Invoker 的方法。
- 第 6 行,Call() 为结构体的方法,该方法的功能是打印 from struct 和传入的 interface{} 类型的值。
将 struct 类型实例化下,并传入接口中进行调用,代码如下:
1 2 3 4 5 6 7 8 9 10 11 | //声明接口的变量 var invoker Invoker //实例化结构体 s := new(Struct) //也可以写成 s := &Struct //将实例化的结构体赋值到接口 invoker = s //使用接口调用实例化结构体的方法 Struct.Call invoker.Call( "hello" ) |
2、函数体实现接口
函数的声明不能直接实现接口,需要将函数定义为类型后,使用类型实现结构体。当类型方法被调用时,还需要调用函数本体。
1 2 3 4 5 6 7 8 | // 函数定义为类型 type FuncCall func ( interface {}) // 实现 Invoker 的 Call func (f FuncCaller) Call(p interface {}){ //调用 f() 函数本体 f(p) } |
代码说明如下:
- 第 2 行,将 func(interface{})定义为 FuncCaller 类型。
- 第 5 行,FuncCaller 的 Call() 方法将实现 Invoker 的 Call() 方法。
- 第 8 行,FuncCaller 的 Call() 方法调用与 func(interface{}) 无关,还需要手动调用函数本体。
上面代码只是定义了函数类型,需要函数本身进行逻辑处理。FuncCaller 无须被实例化,只需要将函数转换为 FuncCaller 类型即可,函数来源可以是命名函数、匿名函数或闭包,代码如下:
1 2 3 4 5 6 7 8 9 10 | //声明接口变量 var invoker Invoker //将匿名函数转为 FuncCaller 类型,再赋值给接口 invoker = FuncCaller( func (v interface {})){ fmt.Println( "from function" , v) } //使用接口调用 FuncCaller.Call,内部会调用函数本体 invoker.Call( "hello" ) |
代码说明如下:
- 第 2 行,声明接口变量。
- 第 5 行,将 func(v interface{}) {} 匿名函数转换为 FuncCaller 类型(函数签名才能转换),此时 FuncCaller 类型实现了 Invoker 的 Call() 方法,赋值给 invoker 接口是成功的。
- 第 10 行,使用接口方法调用。
代码输出如下:
1 | from function hello |
3、HTTP 包中的例子
HTTP 包中包含有 Handler 接口定义,代码如下:
1 2 3 4 5 | package main type Handler interface { ServerHTTP(ResponseWrite, *Request) } |
Handler 用于定义每个 HTTP 请求和响应的处理过程。
同时,也可以使用处理函数实现接口,定义如下:
1 2 3 4 5 | type HandlerFunc func (ResponseWrite, *Request) func (f HandlerFunc) ServerHTTP(w ResponseWrite, r *ResponseWrite){ f(w,r) } |
要使用闭包实现默认的 HTTP 请求处理,可以使用 http.HandleFunc() 函数,函数定义如下:
1 2 3 | func HandlerFunc(pattern string, handler func (ResponseWrite, *Request)){ DefaultServeMux.HandlerFunc(pattern,handler) } |
而 DefaultServMux 是 ServeMux 结构,拥有 HandleFunc() 方法,定义如下:
1 2 3 4 | func (mxu *ServeMux) HandlerFunc(pattern string,hanlder func (ResponseWrite, *Request){ mux.Handle(pattern,HandlerFunc(handler)) } |
上面代码将外部传入的函数 handler() 转为 HandlerFunc 类型,HandlerFunc 类型实现了 Handler 的 ServeHTTP 方法,底层可以同时使用各种类型来实现 Handler 接口进行处理。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具