在中可以通过这样简单实现一个http服务
package mainimport "net/http"func mHttp() {http.HandleFunc("/", h)http.ListenAndServe("0.0.0.0:8888",nil)}func h(w http.ResponseWriter, r *http.Request) {}
http.()是一个注册函数,传一个类型的路由,和一个函数,函数的参数为(http., *http.) 。跟踪进入函数,在 源码net/http/.go文件中
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {DefaultServeMux.HandleFunc(pattern, handler)}
在调用了.(, )
至于这些函数是干啥的先不做探讨,这不是本文的重点 。
再次跟进函数
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {if handler == nil {panic("http: nil handler")}mux.Handle(pattern, HandlerFunc(handler))}
在mux.(, ()) 的第二个参数()是什么鬼 。
文章插图
跟进看一下
type HandlerFunc func(ResponseWriter, *Request)func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {f(w, r)}
原来 是用 type 定义的函数,而函数的类型就是最开始传入的类型
func(, *)
是的一个方法(注意一下,中方法和函数不是一回事) 。并且实现了 接口
接口定义:
type Handler interface {ServeHTTP(ResponseWriter, *Request)}
回到方法中,mux.(, ())的第二个参数是把传入的函数强转成 类型,这样就实现了接口 。
到这我们明白() 是把普通函数强转成type定义的函数 。
文章插图
现在写一个简单的demo验证一下:
package mainimport "fmt"func main() {one(2,callback)}//需要传递函数func callback(i int) {fmt.Println("i am callBack")fmt.Println(i)}//main 中调用的函数func one(i int,f func(int)) {two(i,fun(f))}//one() 中调用的函数func two(i int, c Call) {c.call(i)}//定义的type函数type fun func(int)//fun实现的Call接口的call()函数func (f fun) call(i int) {f(i)}//接口type Call interface {call(int)}
先看一下程序的运行结果:
文章插图
我们在main()函数中调用了one()函数,并传入了()函数,最终调用了我们传入的()函数 。
理一下思路:
使用type定义函数 func(int)
定义 Call 接口,Call中有一个函数 call(int)
在main()中调用one(2, ),在one()中调用two(),传入two()函数前,对函数实现了类型转换,从普通函数转换成type定义的函数 。
【go type func 自定义函数类型】在 two() 中调用传入的 c 因为 c 实现了 Call 接口,所以可以调用 call() 函数,最终调用了我们传入的 () 函数 。
- 泛型编程基础 C++之auto、decltype
- quartz定时任务调度 自定义表单 java图片爬虫
- spring security自定义过滤器
- emark芯片是什么
- Type-C是什么接口
- 代价函数Cost Function ,损失函数Loss Function
- ftp/nfs卸载自定义文件系统数据
- 【损失函数】Keras Loss Function
- Android 自定义控件属性
- 自定义vue组件--实现多图片上传