• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

gotypefunc()自定义函数类型

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

@

目录

    因看不懂 go 中的自定义函数类型,看了https://www.jianshu.com/p/431abe0d2ed5 理解了不少,特此搬运到自己博客

    在看golang 的http服务部分代码时,被golang 中的 type func()写法难住了,一时没看懂代码。后来查资料后,有了一点理解。
    在golang中可以通过这样简单实现一个http服务

    package main
    
    import "net/http"
    
    func mHttp() {
        http.HandleFunc("/", h)
        http.ListenAndServe("0.0.0.0:8888",nil)
    }
    func h(w http.ResponseWriter, r *http.Request) {
    
    }
    

    http.HandleFunc()是一个注册函数,传一个string类型的路由,和一个函数,函数的参数为(http.ResponseWriter, *http.Request)。跟踪进入函数,在golang 源码net/http/server.go文件中

    func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
        DefaultServeMux.HandleFunc(pattern, handler)
    }
    

    在HandleFunc调用了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.Handle(pattern, HandlerFunc(handler)) 的第二个参数HandlerFunc(handler)是什么鬼。
    跟进看一下

    type HandlerFunc func(ResponseWriter, *Request)
    
    func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
        f(w, r)
    }
    

    原来HandlerFunc 是用 type 定义的函数,而函数的类型就是最开始传入的类型
    func(ResponseWriter, *Request)
    ServeHTTP是HandlerFunc的一个方法(注意一下,golang中方法和函数不是一回事)。并且HandlerFunc实现了 Handler接口
    Handler接口定义:

    type Handler interface {
        ServeHTTP(ResponseWriter, *Request)
    }
    

    回到HandleFunc方法中,mux.Handle(pattern, HandlerFunc(handler))的第二个参数是把传入的函数 handler 强转成 HandlerFunc类型,这样handler就实现了Handler接口。
    到这我们明白HandlerFunc(handler) 是把普通函数强转成type定义的函数。
    现在写一个简单的demo验证一下:

    package main
    
    import "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()函数,并传入了callback()函数,最终调用了我们传入的callback()函数。
    理一下思路:
    使用type定义函数 func(int)
    定义 Call 接口,Call中有一个函数 call(int)
    在main()中调用one(2, callback),在one()中调用two(),传入two()函数前,对callback函数实现了类型转换,从普通函数转换成type定义的函数。
    在 two() 中调用传入的 c 因为 c 实现了 Call 接口,所以可以调用 call() 函数,最终调用了我们传入的 callback() 函数。


    鲜花

    握手

    雷人

    路过

    鸡蛋
    该文章已有0人参与评论

    请发表评论

    全部评论

    专题导读
    上一篇:
    ​为什么用Go编写机器学习的基础架构,而不是Python?发布时间:2022-07-10
    下一篇:
    Go 开发者进阶周刊(Dec 3rd)发布时间:2022-07-10
    热门推荐
    热门话题
    阅读排行榜

    扫描微信二维码

    查看手机版网站

    随时了解更新最新资讯

    139-2527-9053

    在线客服(服务时间 9:00~18:00)

    在线QQ客服
    地址:深圳市南山区西丽大学城创智工业园
    电邮:jeky_zhao#qq.com
    移动电话:139-2527-9053

    Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap